1 % -----------------------------------------------------------------------------
2 % $Id: PrelByteArr.lhs,v 1.12 2001/02/22 13:17:58 simonpj 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 )
22 import PrelNum ( fromInt )
25 %*********************************************************
27 \subsection{The @Array@ types}
29 %*********************************************************
32 data Ix ix => ByteArray ix = ByteArray ix ix ByteArray#
33 data Ix ix => MutableByteArray s ix = MutableByteArray ix ix (MutableByteArray# s)
35 instance CCallable (ByteArray ix)
36 instance CCallable (MutableByteArray RealWorld ix)
37 -- Note the RealWorld! You can only ccall with MutableByteArray args
38 -- which are in the real world. When this was missed out, the result
39 -- was that a CCallOpId had a free tyvar, and since the compiler doesn't
40 -- expect that it didn't get zonked or substituted. Bad news.
42 instance Eq (MutableByteArray s ix) where
43 MutableByteArray _ _ arr1# == MutableByteArray _ _ arr2#
44 = sameMutableByteArray# arr1# arr2#
47 %*********************************************************
49 \subsection{Operations on mutable arrays}
51 %*********************************************************
53 Idle ADR question: What's the tradeoff here between flattening these
54 datatypes into @MutableArray ix ix (MutableArray# s elt)@ and using
55 it as is? As I see it, the former uses slightly less heap and
56 provides faster access to the individual parts of the bounds while the
57 code used has the benefit of providing a ready-made @(lo, hi)@ pair as
58 required by many array-related functions. Which wins? Is the
59 difference significant (probably not).
61 Idle AJG answer: When I looked at the outputted code (though it was 2
62 years ago) it seems like you often needed the tuple, and we build
63 it frequently. Now we've got the overloading specialiser things
64 might be different, though.
67 newCharArray, newIntArray, newFloatArray, newDoubleArray
68 :: Ix ix => (ix,ix) -> ST s (MutableByteArray s ix)
70 {-# SPECIALIZE newCharArray :: IPr -> ST s (MutableByteArray s Int) #-}
71 {-# SPECIALIZE newIntArray :: IPr -> ST s (MutableByteArray s Int) #-}
72 {-# SPECIALIZE newFloatArray :: IPr -> ST s (MutableByteArray s Int) #-}
73 {-# SPECIALIZE newDoubleArray :: IPr -> ST s (MutableByteArray s Int) #-}
75 newCharArray (l,u) = ST $ \ s# ->
76 case rangeSize (l,u) of { I# n# ->
77 case (newByteArray# (cHAR_SCALE n#) s#) of { (# s2#, barr# #) ->
78 (# s2#, MutableByteArray l u barr# #) }}
80 newIntArray (l,u) = ST $ \ s# ->
81 case rangeSize (l,u) of { I# n# ->
82 case (newByteArray# (wORD_SCALE n#) s#) of { (# s2#, barr# #) ->
83 (# s2#, MutableByteArray l u barr# #) }}
85 newWordArray (l,u) = ST $ \ s# ->
86 case rangeSize (l,u) of { I# n# ->
87 case (newByteArray# (wORD_SCALE n#) s#) of { (# s2#, barr# #) ->
88 (# s2#, MutableByteArray l u barr# #) }}
90 newFloatArray (l,u) = ST $ \ s# ->
91 case rangeSize (l,u) of { I# n# ->
92 case (newByteArray# (fLOAT_SCALE n#) s#) of { (# s2#, barr# #) ->
93 (# s2#, MutableByteArray l u barr# #) }}
95 newDoubleArray (l,u) = ST $ \ s# ->
96 case rangeSize (l,u) of { I# n# ->
97 case (newByteArray# (dOUBLE_SCALE n#) s#) of { (# s2#, barr# #) ->
98 (# s2#, MutableByteArray l u barr# #) }}
102 -- Char arrays really contain only 8-bit bytes for compatibility.
103 cHAR_SCALE n = 1# *# n
104 wORD_SCALE n = (case SIZEOF_VOID_P :: Int of I# x -> x *# n)
105 dOUBLE_SCALE n = (case SIZEOF_DOUBLE :: Int of I# x -> x *# n)
106 fLOAT_SCALE n = (case SIZEOF_FLOAT :: Int of I# x -> x *# n)
108 readCharArray :: Ix ix => MutableByteArray s ix -> ix -> ST s Char
109 readIntArray :: Ix ix => MutableByteArray s ix -> ix -> ST s Int
110 readFloatArray :: Ix ix => MutableByteArray s ix -> ix -> ST s Float
111 readDoubleArray :: Ix ix => MutableByteArray s ix -> ix -> ST s Double
113 {-# SPECIALIZE readCharArray :: MutableByteArray s Int -> Int -> ST s Char #-}
114 {-# SPECIALIZE readIntArray :: MutableByteArray s Int -> Int -> ST s Int #-}
115 --NO:{-# SPECIALIZE readFloatArray :: MutableByteArray s Int -> Int -> ST s Float #-}
116 {-# SPECIALIZE readDoubleArray :: MutableByteArray s Int -> Int -> ST s Double #-}
118 readCharArray (MutableByteArray l u barr#) n = ST $ \ s# ->
119 case (index (l,u) n) of { I# n# ->
120 case readCharArray# barr# n# s# of { (# s2#, r# #) ->
123 readIntArray (MutableByteArray l u barr#) n = ST $ \ s# ->
124 case (index (l,u) n) of { I# n# ->
125 case readIntArray# barr# n# s# of { (# s2#, r# #) ->
128 readFloatArray (MutableByteArray l u barr#) n = ST $ \ s# ->
129 case (index (l,u) n) of { I# n# ->
130 case readFloatArray# barr# n# s# of { (# s2#, r# #) ->
133 readDoubleArray (MutableByteArray l u barr#) n = ST $ \ s# ->
134 case (index (l,u) n) of { I# n# ->
135 case readDoubleArray# barr# n# s# of { (# s2#, r# #) ->
138 --Indexing of ordinary @Arrays@ is standard Haskell and isn't defined here.
139 indexCharArray :: Ix ix => ByteArray ix -> ix -> Char
140 indexIntArray :: Ix ix => ByteArray ix -> ix -> Int
141 indexFloatArray :: Ix ix => ByteArray ix -> ix -> Float
142 indexDoubleArray :: Ix ix => ByteArray ix -> ix -> Double
144 {-# SPECIALIZE indexCharArray :: ByteArray Int -> Int -> Char #-}
145 {-# SPECIALIZE indexIntArray :: ByteArray Int -> Int -> Int #-}
146 --NO:{-# SPECIALIZE indexFloatArray :: ByteArray Int -> Int -> Float #-}
147 {-# SPECIALIZE indexDoubleArray :: ByteArray Int -> Int -> Double #-}
149 indexCharArray (ByteArray l u barr#) n
150 = case (index (l,u) n) of { I# n# ->
151 case indexCharArray# barr# n# of { r# ->
154 indexIntArray (ByteArray l u barr#) n
155 = case (index (l,u) n) of { I# n# ->
156 case indexIntArray# barr# n# of { r# ->
159 indexFloatArray (ByteArray l u barr#) n
160 = case (index (l,u) n) of { I# n# ->
161 case indexFloatArray# barr# n# of { r# ->
164 indexDoubleArray (ByteArray l u barr#) n
165 = case (index (l,u) n) of { I# n# ->
166 case indexDoubleArray# barr# n# of { r# ->
169 writeCharArray :: Ix ix => MutableByteArray s ix -> ix -> Char -> ST s ()
170 writeIntArray :: Ix ix => MutableByteArray s ix -> ix -> Int -> ST s ()
171 writeFloatArray :: Ix ix => MutableByteArray s ix -> ix -> Float -> ST s ()
172 writeDoubleArray :: Ix ix => MutableByteArray s ix -> ix -> Double -> ST s ()
174 {-# SPECIALIZE writeCharArray :: MutableByteArray s Int -> Int -> Char -> ST s () #-}
175 {-# SPECIALIZE writeIntArray :: MutableByteArray s Int -> Int -> Int -> ST s () #-}
176 --NO:{-# SPECIALIZE writeFloatArray :: MutableByteArray s Int -> Int -> Float -> ST s () #-}
177 {-# SPECIALIZE writeDoubleArray :: MutableByteArray s Int -> Int -> Double -> ST s () #-}
179 writeCharArray (MutableByteArray l u barr#) n (C# ele) = ST $ \ s# ->
180 case index (l,u) n of { I# n# ->
181 case writeCharArray# barr# n# ele s# of { s2# ->
184 writeIntArray (MutableByteArray l u barr#) n (I# ele) = ST $ \ s# ->
185 case index (l,u) n of { I# n# ->
186 case writeIntArray# barr# n# ele s# of { s2# ->
189 writeFloatArray (MutableByteArray l u barr#) n (F# ele) = ST $ \ s# ->
190 case index (l,u) n of { I# n# ->
191 case writeFloatArray# barr# n# ele s# of { s2# ->
194 writeDoubleArray (MutableByteArray l u barr#) n (D# ele) = ST $ \ s# ->
195 case index (l,u) n of { I# n# ->
196 case writeDoubleArray# barr# n# ele s# of { s2# ->