{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, RoleAnnotations #-}{-# OPTIONS_HADDOCK hide #-}------------------------------------------------------------------------------- |-- Module : Data.Array.Storable.Internals-- Copyright : (c) The University of Glasgow 2011-- License : BSD-style (see the file libraries/base/LICENSE)---- Maintainer : libraries@haskell.org-- Stability : experimental-- Portability : non-portable (uses Data.Array.MArray)---- Actual implementation of "Data.Array.Storable".---- @since 0.4.0.0-----------------------------------------------------------------------------moduleData.Array.Storable.Internals(StorableArray (..),withStorableArray ,touchStorableArray ,unsafeForeignPtrToStorableArray ,)whereimportData.Array.Base importData.Array.MArray importForeignhiding(newArray)-- |The array typedataStorableArray i e =StorableArray !i !i Int!(ForeignPtre )-- Both parameters have class-based invariants. See also #9220.typeroleStorableArray nominalnominalinstanceStorablee =>MArray StorableArray e IOwheregetBounds :: forall i. Ix i => StorableArray i e -> IO (i, i) getBounds (StorableArray i l i u Int _ForeignPtr e _)=forall (m :: * -> *) a. Monad m => a -> m a return(i l ,i u )getNumElements :: forall i. Ix i => StorableArray i e -> IO Int getNumElements (StorableArray i _l i _u Int n ForeignPtr e _)=forall (m :: * -> *) a. Monad m => a -> m a returnInt n newArray :: forall i. Ix i => (i, i) -> e -> IO (StorableArray i e) newArray (i l ,i u )e initialValue =doForeignPtr e fp <-forall a. Storable a => Int -> IO (ForeignPtr a) mallocForeignPtrArrayInt size forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b withForeignPtrForeignPtr e fp forall a b. (a -> b) -> a -> b $\Ptr e a ->forall (t :: * -> *) (m :: * -> *) a. (Foldable t, Monad m) => t (m a) -> m () sequence_[forall a. Storable a => Ptr a -> Int -> a -> IO () pokeElemOffPtr e a Int i e initialValue |Int i <-[Int 0..Int size forall a. Num a => a -> a -> a -Int 1]]forall (m :: * -> *) a. Monad m => a -> m a return(forall i e. i -> i -> Int -> ForeignPtr e -> StorableArray i e StorableArray i l i u Int size ForeignPtr e fp )wheresize :: Int size =forall a. Ix a => (a, a) -> Int rangeSize(i l ,i u )unsafeNewArray_ :: forall i. Ix i => (i, i) -> IO (StorableArray i e) unsafeNewArray_ (i l ,i u )=doletn :: Int n =forall a. Ix a => (a, a) -> Int rangeSize(i l ,i u )ForeignPtr e fp <-forall a. Storable a => Int -> IO (ForeignPtr a) mallocForeignPtrArrayInt n forall (m :: * -> *) a. Monad m => a -> m a return(forall i e. i -> i -> Int -> ForeignPtr e -> StorableArray i e StorableArray i l i u Int n ForeignPtr e fp )newArray_ :: forall i. Ix i => (i, i) -> IO (StorableArray i e) newArray_ =forall (a :: * -> * -> *) e (m :: * -> *) i. (MArray a e m, Ix i) => (i, i) -> m (a i e) unsafeNewArray_ unsafeRead :: forall i. Ix i => StorableArray i e -> Int -> IO e unsafeRead (StorableArray i _i _Int _ForeignPtr e fp )Int i =forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b withForeignPtrForeignPtr e fp forall a b. (a -> b) -> a -> b $\Ptr e a ->forall a. Storable a => Ptr a -> Int -> IO a peekElemOffPtr e a Int i unsafeWrite :: forall i. Ix i => StorableArray i e -> Int -> e -> IO () unsafeWrite (StorableArray i _i _Int _ForeignPtr e fp )Int i e e =forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b withForeignPtrForeignPtr e fp forall a b. (a -> b) -> a -> b $\Ptr e a ->forall a. Storable a => Ptr a -> Int -> a -> IO () pokeElemOffPtr e a Int i e e -- |The pointer to the array contents is obtained by 'withStorableArray'.-- The idea is similar to 'ForeignPtr' (used internally here).-- The pointer should be used only during execution of the 'IO' action-- retured by the function passed as argument to 'withStorableArray'.withStorableArray ::StorableArray i e ->(Ptre ->IOa )->IOa withStorableArray :: forall i e a. StorableArray i e -> (Ptr e -> IO a) -> IO a withStorableArray (StorableArray i _i _Int _ForeignPtr e fp )Ptr e -> IO a f =forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b withForeignPtrForeignPtr e fp Ptr e -> IO a f -- |If you want to use it afterwards, ensure that you-- 'touchStorableArray' after the last use of the pointer,-- so the array is not freed too early.touchStorableArray ::StorableArray i e ->IO()touchStorableArray :: forall i e. StorableArray i e -> IO () touchStorableArray (StorableArray i _i _Int _ForeignPtr e fp )=forall a. ForeignPtr a -> IO () touchForeignPtrForeignPtr e fp -- |Construct a 'StorableArray' from an arbitrary 'ForeignPtr'. It is-- the caller's responsibility to ensure that the 'ForeignPtr' points to-- an area of memory sufficient for the specified bounds.unsafeForeignPtrToStorableArray ::Ixi =>ForeignPtre ->(i ,i )->IO(StorableArray i e )unsafeForeignPtrToStorableArray :: forall i e. Ix i => ForeignPtr e -> (i, i) -> IO (StorableArray i e) unsafeForeignPtrToStorableArray ForeignPtr e p (i l ,i u )=forall (m :: * -> *) a. Monad m => a -> m a return(forall i e. i -> i -> Int -> ForeignPtr e -> StorableArray i e StorableArray i l i u (forall a. Ix a => (a, a) -> Int rangeSize(i l ,i u ))ForeignPtr e p )