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