[project @ 2002-04-24 16:31:37 by simonmar]
[packages/random.git] / Data / Array / Storable.hs
1 -----------------------------------------------------------------------------
2 -- |
3 -- Module : Data.Array.Storable
4 -- Copyright : (c) The University of Glasgow 2001
5 -- License : BSD-style (see the file libraries/core/LICENSE)
6 --
7 -- Maintainer : libraries@haskell.org
8 -- Stability : experimental
9 -- Portability : non-portable
10 --
11 -- $Id: Storable.hs,v 1.3 2002/04/24 16:31:43 simonmar Exp $
12 --
13 -- A storable array is an IO-mutable array which stores its
14 -- contents in a contiguous memory block living in the C
15 -- heap. Elements are stored according to the class Storable.
16 -- You can obtain the pointer to the array contents to manipulate
17 -- elements from languages like C.
18 --
19 -- It's similar to IOUArray but slower. Its advantage is that
20 -- it's compatible with C.
21 --
22 -----------------------------------------------------------------------------
23
24 module Data.Array.Storable (
25
26 -- Array type:
27 StorableArray, -- data StorableArray index element
28 -- -- index type must be in class Ix
29 -- -- element type must be in class Storable
30
31 -- Module MArray provides the interface of storable arrays.
32 -- They are instances of class MArray (with IO monad).
33 module Data.Array.MArray,
34
35 -- The pointer to the array contents is obtained by withStorableArray.
36 -- The idea is similar to ForeignPtr (used internally here). The
37 -- pointer should be used only during execution of the IO action
38 -- retured by the function passed as argument to withStorableArray:
39 withStorableArray, -- :: StorableArray i e -> (Ptr e -> IO a) -> IO a
40
41 -- If you want to use it afterwards, ensure that you
42 -- touchStorableArray after the last use of the pointer,
43 -- so the array is not freed too early:
44 touchStorableArray -- :: StorableArray i e -> IO ()
45 )
46 where
47
48 import Prelude
49
50 import Data.Array.Base
51 import Data.Array.MArray
52 import Foreign hiding (newArray)
53
54 data StorableArray i e = StorableArray !i !i !(ForeignPtr e)
55
56 instance HasBounds StorableArray where
57 bounds (StorableArray l u _) = (l,u)
58
59 instance Storable e => MArray StorableArray e IO where
60
61 newArray (l,u) init = do
62 a <- mallocArray size
63 sequence_ [pokeElemOff a i init | i <- [0..size-1]]
64 fp <- newForeignPtr a (free a)
65 return (StorableArray l u fp)
66 where
67 size = rangeSize (l,u)
68
69 newArray_ (l,u) = do
70 a <- mallocArray (rangeSize (l,u))
71 fp <- newForeignPtr a (free a)
72 return (StorableArray l u fp)
73
74 unsafeRead (StorableArray _ _ fp) i =
75 withForeignPtr fp $ \a -> peekElemOff a i
76
77 unsafeWrite (StorableArray _ _ fp) i e =
78 withForeignPtr fp $ \a -> pokeElemOff a i e
79
80 withStorableArray :: StorableArray i e -> (Ptr e -> IO a) -> IO a
81 withStorableArray (StorableArray _ _ fp) f = withForeignPtr fp f
82
83 touchStorableArray :: StorableArray i e -> IO ()
84 touchStorableArray (StorableArray _ _ fp) = touchForeignPtr fp