[project @ 2001-07-04 10:48:39 by simonmar]
[ghc-base.git] / Data / Array / Storable.hs
diff --git a/Data/Array/Storable.hs b/Data/Array/Storable.hs
new file mode 100644 (file)
index 0000000..e725d2d
--- /dev/null
@@ -0,0 +1,82 @@
+-----------------------------------------------------------------------------
+-- 
+-- Module      :  Data.Array.Storable
+-- Copyright   :  (c) The University of Glasgow 2001
+-- License     :  BSD-style (see the file libraries/core/LICENSE)
+-- 
+-- Maintainer  :  libraries@haskell.org
+-- Stability   :  experimental
+-- Portability :  non-portable
+--
+-- $Id: Storable.hs,v 1.1 2001/07/04 10:48:39 simonmar Exp $
+--
+-- A storable array is an IO-mutable array which stores its
+-- contents in a contiguous memory block living in the C
+-- heap. Elements are stored according to the class Storable.
+-- You can obtain the pointer to the array contents to manipulate
+-- elements from languages like C.
+--
+-- It's similar to IOUArray but slower. Its advantage is that
+-- it's compatible with C.
+--
+-----------------------------------------------------------------------------
+
+module Data.Array.Storable (
+    
+    -- Array type:
+    StorableArray, -- data StorableArray index element
+                   --     -- index type must be in class Ix
+                   --     -- element type must be in class Storable
+    
+    -- Module MArray provides the interface of storable arrays.
+    -- They are instances of class MArray (with IO monad).
+    module Data.Array.MArray,
+    
+    -- 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 -> (Ptr e -> IO a) -> IO a
+    
+    -- 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 ()
+    )
+    where
+
+import Data.Array.Base
+import Data.Array.MArray
+import Foreign hiding (newArray)
+
+data StorableArray i e = StorableArray !i !i !(ForeignPtr e)
+
+instance HasBounds StorableArray where
+    bounds (StorableArray l u _) = (l,u)
+
+instance Storable e => MArray StorableArray e IO where
+
+    newArray (l,u) init = do
+        a <- mallocArray size
+        sequence_ [pokeElemOff a i init | i <- [0..size-1]]
+        fp <- newForeignPtr a (free a)
+        return (StorableArray l u fp)
+        where
+        size = rangeSize (l,u)
+
+    newArray_ (l,u) = do
+        a  <- mallocArray (rangeSize (l,u))
+        fp <- newForeignPtr a (free a)
+        return (StorableArray l u fp)
+
+    unsafeRead (StorableArray _ _ fp) i =
+        withForeignPtr fp $ \a -> peekElemOff a i
+
+    unsafeWrite (StorableArray _ _ fp) i e =
+        withForeignPtr fp $ \a -> pokeElemOff a i e
+
+withStorableArray :: StorableArray i e -> (Ptr e -> IO a) -> IO a
+withStorableArray (StorableArray _ _ fp) f = withForeignPtr fp f
+
+touchStorableArray :: StorableArray i e -> IO ()
+touchStorableArray (StorableArray _ _ fp) = touchForeignPtr fp