1 % -----------------------------------------------------------------------------
2 % $Id: PrelByteArr.lhs,v 1.13 2001/02/22 16:48:24 qrczak Exp $
4 % (c) The University of Glasgow, 1994-2000
7 \section[PrelByteArr]{Module @PrelByteArr@}
9 Byte-arrays are flat arrays of non-pointers only.
12 {-# OPTIONS -fno-implicit-prelude #-}
14 module PrelByteArr where
16 import {-# SOURCE #-} PrelErr ( error )
24 %*********************************************************
26 \subsection{The @Array@ types}
28 %*********************************************************
31 data Ix ix => ByteArray ix = ByteArray ix ix ByteArray#
32 data Ix ix => MutableByteArray s ix = MutableByteArray ix ix (MutableByteArray# s)
34 instance CCallable (ByteArray ix)
35 instance CCallable (MutableByteArray RealWorld ix)
36 -- Note the RealWorld! You can only ccall with MutableByteArray args
37 -- which are in the real world. When this was missed out, the result
38 -- was that a CCallOpId had a free tyvar, and since the compiler doesn't
39 -- expect that it didn't get zonked or substituted. Bad news.
41 instance Eq (MutableByteArray s ix) where
42 MutableByteArray _ _ arr1# == MutableByteArray _ _ arr2#
43 = sameMutableByteArray# arr1# arr2#
46 %*********************************************************
48 \subsection{Operations on mutable arrays}
50 %*********************************************************
52 Idle ADR question: What's the tradeoff here between flattening these
53 datatypes into @MutableArray ix ix (MutableArray# s elt)@ and using
54 it as is? As I see it, the former uses slightly less heap and
55 provides faster access to the individual parts of the bounds while the
56 code used has the benefit of providing a ready-made @(lo, hi)@ pair as
57 required by many array-related functions. Which wins? Is the
58 difference significant (probably not).
60 Idle AJG answer: When I looked at the outputted code (though it was 2
61 years ago) it seems like you often needed the tuple, and we build
62 it frequently. Now we've got the overloading specialiser things
63 might be different, though.
66 newCharArray, newIntArray, newFloatArray, newDoubleArray
67 :: Ix ix => (ix,ix) -> ST s (MutableByteArray s ix)
69 {-# SPECIALIZE newCharArray :: IPr -> ST s (MutableByteArray s Int) #-}
70 {-# SPECIALIZE newIntArray :: IPr -> ST s (MutableByteArray s Int) #-}
71 {-# SPECIALIZE newFloatArray :: IPr -> ST s (MutableByteArray s Int) #-}
72 {-# SPECIALIZE newDoubleArray :: IPr -> ST s (MutableByteArray s Int) #-}
74 newCharArray (l,u) = ST $ \ s# ->
75 case rangeSize (l,u) of { I# n# ->
76 case (newByteArray# (cHAR_SCALE n#) s#) of { (# s2#, barr# #) ->
77 (# s2#, MutableByteArray l u barr# #) }}
79 newIntArray (l,u) = ST $ \ s# ->
80 case rangeSize (l,u) of { I# n# ->
81 case (newByteArray# (wORD_SCALE n#) s#) of { (# s2#, barr# #) ->
82 (# s2#, MutableByteArray l u barr# #) }}
84 newWordArray (l,u) = ST $ \ s# ->
85 case rangeSize (l,u) of { I# n# ->
86 case (newByteArray# (wORD_SCALE n#) s#) of { (# s2#, barr# #) ->
87 (# s2#, MutableByteArray l u barr# #) }}
89 newFloatArray (l,u) = ST $ \ s# ->
90 case rangeSize (l,u) of { I# n# ->
91 case (newByteArray# (fLOAT_SCALE n#) s#) of { (# s2#, barr# #) ->
92 (# s2#, MutableByteArray l u barr# #) }}
94 newDoubleArray (l,u) = ST $ \ s# ->
95 case rangeSize (l,u) of { I# n# ->
96 case (newByteArray# (dOUBLE_SCALE n#) s#) of { (# s2#, barr# #) ->
97 (# s2#, MutableByteArray l u barr# #) }}
101 -- Char arrays really contain only 8-bit bytes for compatibility.
102 cHAR_SCALE n = 1# *# n
103 wORD_SCALE n = (case SIZEOF_VOID_P :: Int of I# x -> x *# n)
104 dOUBLE_SCALE n = (case SIZEOF_DOUBLE :: Int of I# x -> x *# n)
105 fLOAT_SCALE n = (case SIZEOF_FLOAT :: Int of I# x -> x *# n)
107 readCharArray :: Ix ix => MutableByteArray s ix -> ix -> ST s Char
108 readIntArray :: Ix ix => MutableByteArray s ix -> ix -> ST s Int
109 readFloatArray :: Ix ix => MutableByteArray s ix -> ix -> ST s Float
110 readDoubleArray :: Ix ix => MutableByteArray s ix -> ix -> ST s Double
112 {-# SPECIALIZE readCharArray :: MutableByteArray s Int -> Int -> ST s Char #-}
113 {-# SPECIALIZE readIntArray :: MutableByteArray s Int -> Int -> ST s Int #-}
114 --NO:{-# SPECIALIZE readFloatArray :: MutableByteArray s Int -> Int -> ST s Float #-}
115 {-# SPECIALIZE readDoubleArray :: MutableByteArray s Int -> Int -> ST s Double #-}
117 readCharArray (MutableByteArray l u barr#) n = ST $ \ s# ->
118 case (index (l,u) n) of { I# n# ->
119 case readCharArray# barr# n# s# of { (# s2#, r# #) ->
122 readIntArray (MutableByteArray l u barr#) n = ST $ \ s# ->
123 case (index (l,u) n) of { I# n# ->
124 case readIntArray# barr# n# s# of { (# s2#, r# #) ->
127 readFloatArray (MutableByteArray l u barr#) n = ST $ \ s# ->
128 case (index (l,u) n) of { I# n# ->
129 case readFloatArray# barr# n# s# of { (# s2#, r# #) ->
132 readDoubleArray (MutableByteArray l u barr#) n = ST $ \ s# ->
133 case (index (l,u) n) of { I# n# ->
134 case readDoubleArray# barr# n# s# of { (# s2#, r# #) ->
137 --Indexing of ordinary @Arrays@ is standard Haskell and isn't defined here.
138 indexCharArray :: Ix ix => ByteArray ix -> ix -> Char
139 indexIntArray :: Ix ix => ByteArray ix -> ix -> Int
140 indexFloatArray :: Ix ix => ByteArray ix -> ix -> Float
141 indexDoubleArray :: Ix ix => ByteArray ix -> ix -> Double
143 {-# SPECIALIZE indexCharArray :: ByteArray Int -> Int -> Char #-}
144 {-# SPECIALIZE indexIntArray :: ByteArray Int -> Int -> Int #-}
145 --NO:{-# SPECIALIZE indexFloatArray :: ByteArray Int -> Int -> Float #-}
146 {-# SPECIALIZE indexDoubleArray :: ByteArray Int -> Int -> Double #-}
148 indexCharArray (ByteArray l u barr#) n
149 = case (index (l,u) n) of { I# n# ->
150 case indexCharArray# barr# n# of { r# ->
153 indexIntArray (ByteArray l u barr#) n
154 = case (index (l,u) n) of { I# n# ->
155 case indexIntArray# barr# n# of { r# ->
158 indexFloatArray (ByteArray l u barr#) n
159 = case (index (l,u) n) of { I# n# ->
160 case indexFloatArray# barr# n# of { r# ->
163 indexDoubleArray (ByteArray l u barr#) n
164 = case (index (l,u) n) of { I# n# ->
165 case indexDoubleArray# barr# n# of { r# ->
168 writeCharArray :: Ix ix => MutableByteArray s ix -> ix -> Char -> ST s ()
169 writeIntArray :: Ix ix => MutableByteArray s ix -> ix -> Int -> ST s ()
170 writeFloatArray :: Ix ix => MutableByteArray s ix -> ix -> Float -> ST s ()
171 writeDoubleArray :: Ix ix => MutableByteArray s ix -> ix -> Double -> ST s ()
173 {-# SPECIALIZE writeCharArray :: MutableByteArray s Int -> Int -> Char -> ST s () #-}
174 {-# SPECIALIZE writeIntArray :: MutableByteArray s Int -> Int -> Int -> ST s () #-}
175 --NO:{-# SPECIALIZE writeFloatArray :: MutableByteArray s Int -> Int -> Float -> ST s () #-}
176 {-# SPECIALIZE writeDoubleArray :: MutableByteArray s Int -> Int -> Double -> ST s () #-}
178 writeCharArray (MutableByteArray l u barr#) n (C# ele) = ST $ \ s# ->
179 case index (l,u) n of { I# n# ->
180 case writeCharArray# barr# n# ele s# of { s2# ->
183 writeIntArray (MutableByteArray l u barr#) n (I# ele) = ST $ \ s# ->
184 case index (l,u) n of { I# n# ->
185 case writeIntArray# barr# n# ele s# of { s2# ->
188 writeFloatArray (MutableByteArray l u barr#) n (F# ele) = ST $ \ s# ->
189 case index (l,u) n of { I# n# ->
190 case writeFloatArray# barr# n# ele s# of { s2# ->
193 writeDoubleArray (MutableByteArray l u barr#) n (D# ele) = ST $ \ s# ->
194 case index (l,u) n of { I# n# ->
195 case writeDoubleArray# barr# n# ele s# of { s2# ->