FIX #1131 (newArray_ allocates an array full of garbage)
[ghc-base.git] / Data / Array / IO / Internals.hs
1 {-# OPTIONS_GHC -#include "HsBase.h" #-}
2 -----------------------------------------------------------------------------
3 -- |
4 -- Module      :  Data.Array.IO.Internal
5 -- Copyright   :  (c) The University of Glasgow 2001
6 -- License     :  BSD-style (see the file libraries/base/LICENSE)
7 -- 
8 -- Maintainer  :  libraries@haskell.org
9 -- Stability   :  experimental
10 -- Portability :  non-portable (uses Data.Array.Base)
11 --
12 -- Mutable boxed and unboxed arrays in the IO monad.
13 --
14 -----------------------------------------------------------------------------
15
16 -- #hide
17 module Data.Array.IO.Internals (
18    IOArray(..),         -- instance of: Eq, Typeable
19    IOUArray(..),        -- instance of: Eq, Typeable
20    castIOUArray,        -- :: IOUArray ix a -> IO (IOUArray ix b)
21  ) where
22
23 import Prelude
24
25 import Data.Array.MArray
26 import Data.Int
27 import Data.Word
28 import Data.Typeable
29
30 #ifdef __HUGS__
31 import Hugs.IOArray
32 #endif
33
34 import Control.Monad.ST         ( RealWorld, stToIO )
35 import Foreign.Ptr              ( Ptr, FunPtr )
36 import Foreign.StablePtr        ( StablePtr )
37 import Data.Array.Base
38
39 #ifdef __GLASGOW_HASKELL__
40 import GHC.IOBase
41 import GHC.Base
42 #endif /* __GLASGOW_HASKELL__ */
43
44 #include "Typeable.h"
45
46 INSTANCE_TYPEABLE2(IOArray,iOArrayTc,"IOArray")
47
48 -----------------------------------------------------------------------------
49 -- | Instance declarations for 'IOArray's
50
51 instance MArray IOArray e IO where
52 #if defined(__HUGS__)
53     getBounds   = return . boundsIOArray
54 #elif defined(__GLASGOW_HASKELL__)
55     {-# INLINE getBounds #-}
56     getBounds (IOArray marr) = stToIO $ getBounds marr
57 #endif
58     newArray    = newIOArray
59     unsafeRead  = unsafeReadIOArray
60     unsafeWrite = unsafeWriteIOArray
61
62 -----------------------------------------------------------------------------
63 -- Flat unboxed mutable arrays (IO monad)
64
65 -- | Mutable, unboxed, strict arrays in the 'IO' monad.  The type
66 -- arguments are as follows:
67 --
68 --  * @i@: the index type of the array (should be an instance of 'Ix')
69 --
70 --  * @e@: the element type of the array.  Only certain element types
71 --    are supported: see "Data.Array.MArray" for a list of instances.
72 --
73 newtype IOUArray i e = IOUArray (STUArray RealWorld i e)
74
75 INSTANCE_TYPEABLE2(IOUArray,iOUArrayTc,"IOUArray")
76
77 instance MArray IOUArray Bool IO where
78     {-# INLINE getBounds #-}
79     getBounds (IOUArray arr) = stToIO $ getBounds arr
80     {-# INLINE newArray #-}
81     newArray lu init = stToIO $ do
82         marr <- newArray lu init; return (IOUArray marr)
83     {-# INLINE unsafeNewArray_ #-}
84     unsafeNewArray_ lu = stToIO $ do
85         marr <- unsafeNewArray_ lu; return (IOUArray marr)
86     {-# INLINE newArray_ #-}
87     newArray_ = unsafeNewArray_
88     {-# INLINE unsafeRead #-}
89     unsafeRead (IOUArray marr) i = stToIO (unsafeRead marr i)
90     {-# INLINE unsafeWrite #-}
91     unsafeWrite (IOUArray marr) i e = stToIO (unsafeWrite marr i e)
92
93 instance MArray IOUArray Char IO where
94     {-# INLINE getBounds #-}
95     getBounds (IOUArray arr) = stToIO $ getBounds arr
96     {-# INLINE newArray #-}
97     newArray lu init = stToIO $ do
98         marr <- newArray lu init; return (IOUArray marr)
99     {-# INLINE unsafeNewArray_ #-}
100     unsafeNewArray_ lu = stToIO $ do
101         marr <- unsafeNewArray_ lu; return (IOUArray marr)
102     {-# INLINE newArray_ #-}
103     newArray_ = unsafeNewArray_
104     {-# INLINE unsafeRead #-}
105     unsafeRead (IOUArray marr) i = stToIO (unsafeRead marr i)
106     {-# INLINE unsafeWrite #-}
107     unsafeWrite (IOUArray marr) i e = stToIO (unsafeWrite marr i e)
108
109 instance MArray IOUArray Int IO where
110     {-# INLINE getBounds #-}
111     getBounds (IOUArray arr) = stToIO $ getBounds arr
112     {-# INLINE newArray #-}
113     newArray lu init = stToIO $ do
114         marr <- newArray lu init; return (IOUArray marr)
115     {-# INLINE unsafeNewArray_ #-}
116     unsafeNewArray_ lu = stToIO $ do
117         marr <- unsafeNewArray_ lu; return (IOUArray marr)
118     {-# INLINE newArray_ #-}
119     newArray_ = unsafeNewArray_
120     {-# INLINE unsafeRead #-}
121     unsafeRead (IOUArray marr) i = stToIO (unsafeRead marr i)
122     {-# INLINE unsafeWrite #-}
123     unsafeWrite (IOUArray marr) i e = stToIO (unsafeWrite marr i e)
124
125 instance MArray IOUArray Word IO where
126     {-# INLINE getBounds #-}
127     getBounds (IOUArray arr) = stToIO $ getBounds arr
128     {-# INLINE newArray #-}
129     newArray lu init = stToIO $ do
130         marr <- newArray lu init; return (IOUArray marr)
131     {-# INLINE unsafeNewArray_ #-}
132     unsafeNewArray_ lu = stToIO $ do
133         marr <- unsafeNewArray_ lu; return (IOUArray marr)
134     {-# INLINE newArray_ #-}
135     newArray_ = unsafeNewArray_
136     {-# INLINE unsafeRead #-}
137     unsafeRead (IOUArray marr) i = stToIO (unsafeRead marr i)
138     {-# INLINE unsafeWrite #-}
139     unsafeWrite (IOUArray marr) i e = stToIO (unsafeWrite marr i e)
140
141 instance MArray IOUArray (Ptr a) IO where
142     {-# INLINE getBounds #-}
143     getBounds (IOUArray arr) = stToIO $ getBounds arr
144     {-# INLINE newArray #-}
145     newArray lu init = stToIO $ do
146         marr <- newArray lu init; return (IOUArray marr)
147     {-# INLINE unsafeNewArray_ #-}
148     unsafeNewArray_ lu = stToIO $ do
149         marr <- unsafeNewArray_ lu; return (IOUArray marr)
150     {-# INLINE newArray_ #-}
151     newArray_ = unsafeNewArray_
152     {-# INLINE unsafeRead #-}
153     unsafeRead (IOUArray marr) i = stToIO (unsafeRead marr i)
154     {-# INLINE unsafeWrite #-}
155     unsafeWrite (IOUArray marr) i e = stToIO (unsafeWrite marr i e)
156
157 instance MArray IOUArray (FunPtr a) IO where
158     {-# INLINE getBounds #-}
159     getBounds (IOUArray arr) = stToIO $ getBounds arr
160     {-# INLINE newArray #-}
161     newArray lu init = stToIO $ do
162         marr <- newArray lu init; return (IOUArray marr)
163     {-# INLINE unsafeNewArray_ #-}
164     unsafeNewArray_ lu = stToIO $ do
165         marr <- unsafeNewArray_ lu; return (IOUArray marr)
166     {-# INLINE newArray_ #-}
167     newArray_ = unsafeNewArray_
168     {-# INLINE unsafeRead #-}
169     unsafeRead (IOUArray marr) i = stToIO (unsafeRead marr i)
170     {-# INLINE unsafeWrite #-}
171     unsafeWrite (IOUArray marr) i e = stToIO (unsafeWrite marr i e)
172
173 instance MArray IOUArray Float IO where
174     {-# INLINE getBounds #-}
175     getBounds (IOUArray arr) = stToIO $ getBounds arr
176     {-# INLINE newArray #-}
177     newArray lu init = stToIO $ do
178         marr <- newArray lu init; return (IOUArray marr)
179     {-# INLINE unsafeNewArray_ #-}
180     unsafeNewArray_ lu = stToIO $ do
181         marr <- unsafeNewArray_ lu; return (IOUArray marr)
182     {-# INLINE newArray_ #-}
183     newArray_ = unsafeNewArray_
184     {-# INLINE unsafeRead #-}
185     unsafeRead (IOUArray marr) i = stToIO (unsafeRead marr i)
186     {-# INLINE unsafeWrite #-}
187     unsafeWrite (IOUArray marr) i e = stToIO (unsafeWrite marr i e)
188
189 instance MArray IOUArray Double IO where
190     {-# INLINE getBounds #-}
191     getBounds (IOUArray arr) = stToIO $ getBounds arr
192     {-# INLINE newArray #-}
193     newArray lu init = stToIO $ do
194         marr <- newArray lu init; return (IOUArray marr)
195     {-# INLINE unsafeNewArray_ #-}
196     unsafeNewArray_ lu = stToIO $ do
197         marr <- unsafeNewArray_ lu; return (IOUArray marr)
198     {-# INLINE newArray_ #-}
199     newArray_ = unsafeNewArray_
200     {-# INLINE unsafeRead #-}
201     unsafeRead (IOUArray marr) i = stToIO (unsafeRead marr i)
202     {-# INLINE unsafeWrite #-}
203     unsafeWrite (IOUArray marr) i e = stToIO (unsafeWrite marr i e)
204
205 instance MArray IOUArray (StablePtr a) IO where
206     {-# INLINE getBounds #-}
207     getBounds (IOUArray arr) = stToIO $ getBounds arr
208     {-# INLINE newArray #-}
209     newArray lu init = stToIO $ do
210         marr <- newArray lu init; return (IOUArray marr)
211     {-# INLINE unsafeNewArray_ #-}
212     unsafeNewArray_ lu = stToIO $ do
213         marr <- unsafeNewArray_ lu; return (IOUArray marr)
214     {-# INLINE newArray_ #-}
215     newArray_ = unsafeNewArray_
216     {-# INLINE unsafeRead #-}
217     unsafeRead (IOUArray marr) i = stToIO (unsafeRead marr i)
218     {-# INLINE unsafeWrite #-}
219     unsafeWrite (IOUArray marr) i e = stToIO (unsafeWrite marr i e)
220
221 instance MArray IOUArray Int8 IO where
222     {-# INLINE getBounds #-}
223     getBounds (IOUArray arr) = stToIO $ getBounds arr
224     {-# INLINE newArray #-}
225     newArray lu init = stToIO $ do
226         marr <- newArray lu init; return (IOUArray marr)
227     {-# INLINE unsafeNewArray_ #-}
228     unsafeNewArray_ lu = stToIO $ do
229         marr <- unsafeNewArray_ lu; return (IOUArray marr)
230     {-# INLINE newArray_ #-}
231     newArray_ = unsafeNewArray_
232     {-# INLINE unsafeRead #-}
233     unsafeRead (IOUArray marr) i = stToIO (unsafeRead marr i)
234     {-# INLINE unsafeWrite #-}
235     unsafeWrite (IOUArray marr) i e = stToIO (unsafeWrite marr i e)
236
237 instance MArray IOUArray Int16 IO where
238     {-# INLINE getBounds #-}
239     getBounds (IOUArray arr) = stToIO $ getBounds arr
240     {-# INLINE newArray #-}
241     newArray lu init = stToIO $ do
242         marr <- newArray lu init; return (IOUArray marr)
243     {-# INLINE unsafeNewArray_ #-}
244     unsafeNewArray_ lu = stToIO $ do
245         marr <- unsafeNewArray_ lu; return (IOUArray marr)
246     {-# INLINE newArray_ #-}
247     newArray_ = unsafeNewArray_
248     {-# INLINE unsafeRead #-}
249     unsafeRead (IOUArray marr) i = stToIO (unsafeRead marr i)
250     {-# INLINE unsafeWrite #-}
251     unsafeWrite (IOUArray marr) i e = stToIO (unsafeWrite marr i e)
252
253 instance MArray IOUArray Int32 IO where
254     {-# INLINE getBounds #-}
255     getBounds (IOUArray arr) = stToIO $ getBounds arr
256     {-# INLINE newArray #-}
257     newArray lu init = stToIO $ do
258         marr <- newArray lu init; return (IOUArray marr)
259     {-# INLINE unsafeNewArray_ #-}
260     unsafeNewArray_ lu = stToIO $ do
261         marr <- unsafeNewArray_ lu; return (IOUArray marr)
262     {-# INLINE newArray_ #-}
263     newArray_ = unsafeNewArray_
264     {-# INLINE unsafeRead #-}
265     unsafeRead (IOUArray marr) i = stToIO (unsafeRead marr i)
266     {-# INLINE unsafeWrite #-}
267     unsafeWrite (IOUArray marr) i e = stToIO (unsafeWrite marr i e)
268
269 instance MArray IOUArray Int64 IO where
270     {-# INLINE getBounds #-}
271     getBounds (IOUArray arr) = stToIO $ getBounds arr
272     {-# INLINE newArray #-}
273     newArray lu init = stToIO $ do
274         marr <- newArray lu init; return (IOUArray marr)
275     {-# INLINE unsafeNewArray_ #-}
276     unsafeNewArray_ lu = stToIO $ do
277         marr <- unsafeNewArray_ lu; return (IOUArray marr)
278     {-# INLINE newArray_ #-}
279     newArray_ = unsafeNewArray_
280     {-# INLINE unsafeRead #-}
281     unsafeRead (IOUArray marr) i = stToIO (unsafeRead marr i)
282     {-# INLINE unsafeWrite #-}
283     unsafeWrite (IOUArray marr) i e = stToIO (unsafeWrite marr i e)
284
285 instance MArray IOUArray Word8 IO where
286     {-# INLINE getBounds #-}
287     getBounds (IOUArray arr) = stToIO $ getBounds arr
288     {-# INLINE newArray #-}
289     newArray lu init = stToIO $ do
290         marr <- newArray lu init; return (IOUArray marr)
291     {-# INLINE unsafeNewArray_ #-}
292     unsafeNewArray_ lu = stToIO $ do
293         marr <- unsafeNewArray_ lu; return (IOUArray marr)
294     {-# INLINE newArray_ #-}
295     newArray_ = unsafeNewArray_
296     {-# INLINE unsafeRead #-}
297     unsafeRead (IOUArray marr) i = stToIO (unsafeRead marr i)
298     {-# INLINE unsafeWrite #-}
299     unsafeWrite (IOUArray marr) i e = stToIO (unsafeWrite marr i e)
300
301 instance MArray IOUArray Word16 IO where
302     {-# INLINE getBounds #-}
303     getBounds (IOUArray arr) = stToIO $ getBounds arr
304     {-# INLINE newArray #-}
305     newArray lu init = stToIO $ do
306         marr <- newArray lu init; return (IOUArray marr)
307     {-# INLINE unsafeNewArray_ #-}
308     unsafeNewArray_ lu = stToIO $ do
309         marr <- unsafeNewArray_ lu; return (IOUArray marr)
310     {-# INLINE newArray_ #-}
311     newArray_ = unsafeNewArray_
312     {-# INLINE unsafeRead #-}
313     unsafeRead (IOUArray marr) i = stToIO (unsafeRead marr i)
314     {-# INLINE unsafeWrite #-}
315     unsafeWrite (IOUArray marr) i e = stToIO (unsafeWrite marr i e)
316
317 instance MArray IOUArray Word32 IO where
318     {-# INLINE getBounds #-}
319     getBounds (IOUArray arr) = stToIO $ getBounds arr
320     {-# INLINE newArray #-}
321     newArray lu init = stToIO $ do
322         marr <- newArray lu init; return (IOUArray marr)
323     {-# INLINE unsafeNewArray_ #-}
324     unsafeNewArray_ lu = stToIO $ do
325         marr <- unsafeNewArray_ lu; return (IOUArray marr)
326     {-# INLINE newArray_ #-}
327     newArray_ = unsafeNewArray_
328     {-# INLINE unsafeRead #-}
329     unsafeRead (IOUArray marr) i = stToIO (unsafeRead marr i)
330     {-# INLINE unsafeWrite #-}
331     unsafeWrite (IOUArray marr) i e = stToIO (unsafeWrite marr i e)
332
333 instance MArray IOUArray Word64 IO where
334     {-# INLINE getBounds #-}
335     getBounds (IOUArray arr) = stToIO $ getBounds arr
336     {-# INLINE newArray #-}
337     newArray lu init = stToIO $ do
338         marr <- newArray lu init; return (IOUArray marr)
339     {-# INLINE unsafeNewArray_ #-}
340     unsafeNewArray_ lu = stToIO $ do
341         marr <- unsafeNewArray_ lu; return (IOUArray marr)
342     {-# INLINE newArray_ #-}
343     newArray_ = unsafeNewArray_
344     {-# INLINE unsafeRead #-}
345     unsafeRead (IOUArray marr) i = stToIO (unsafeRead marr i)
346     {-# INLINE unsafeWrite #-}
347     unsafeWrite (IOUArray marr) i e = stToIO (unsafeWrite marr i e)
348
349 -- | Casts an 'IOUArray' with one element type into one with a
350 -- different element type.  All the elements of the resulting array
351 -- are undefined (unless you know what you\'re doing...).
352 castIOUArray :: IOUArray ix a -> IO (IOUArray ix b)
353 castIOUArray (IOUArray marr) = stToIO $ do
354     marr' <- castSTUArray marr
355     return (IOUArray marr')
356