24
24
module Data.Text.Array
25
25
(
26
26
-- * Types
27
- Array (Array , aBA )
28
- , MArray (MArray , maBA )
29
-
27
+ Array (.. )
28
+ , MArray (.. )
30
29
-- * Functions
31
30
, copyM
32
31
, copyI
33
32
, empty
34
33
, equal
35
- #if defined(ASSERTS)
36
- , length
37
- #endif
38
34
, run
39
35
, run2
40
36
, toList
@@ -44,17 +40,6 @@ module Data.Text.Array
44
40
, unsafeWrite
45
41
) where
46
42
47
- #if defined(ASSERTS)
48
- -- This fugly hack is brought by GHC's apparent reluctance to deal
49
- -- with MagicHash and UnboxedTuples when inferring types. Eek!
50
- # define CHECK_BOUNDS(_func_,_len_,_k_) \
51
- if (_k_) < 0 || (_k_) >= (_len_) then error (" Data.Text.Array." ++ (_func_) ++ " : bounds error, offset " ++ show (_k_) ++ " , length " ++ show (_len_)) else
52
- #else
53
- # define CHECK_BOUNDS(_func_,_len_,_k_)
54
- #endif
55
-
56
- #include "MachDeps.h"
57
-
58
43
#if defined(ASSERTS)
59
44
import Control.Exception (assert )
60
45
#endif
@@ -73,57 +58,28 @@ import Foreign.C.Types (CInt, CSize)
73
58
#endif
74
59
import GHC.Base (ByteArray #, MutableByteArray #, Int (.. ),
75
60
indexWord16Array #, newByteArray #,
76
- unsafeFreezeByteArray #, writeWord16Array #)
61
+ unsafeFreezeByteArray #, writeWord16Array #, sizeofByteArray #, sizeofMutableByteArray # )
77
62
import GHC.ST (ST (.. ), runST )
78
63
import GHC.Word (Word16 (.. ))
79
64
import Prelude hiding (length , read )
80
65
81
66
-- | Immutable array type.
82
67
--
83
68
-- The 'Array' constructor is exposed since @text-1.1.1.3@
84
- data Array = Array {
85
- aBA :: ByteArray #
86
- # if defined (ASSERTS )
87
- , aLen :: {-# UNPACK #-} ! Int -- length (in units of Word16, not bytes)
88
- # endif
89
- }
69
+ data Array = Array { aBA :: ByteArray # }
90
70
91
71
-- | Mutable array type, for use in the ST monad.
92
72
--
93
73
-- The 'MArray' constructor is exposed since @text-1.1.1.3@
94
- data MArray s = MArray {
95
- maBA :: MutableByteArray # s
96
- # if defined (ASSERTS )
97
- , maLen :: {-# UNPACK #-} ! Int -- length (in units of Word16, not bytes)
98
- # endif
99
- }
100
-
101
- #if defined(ASSERTS)
102
- -- | Operations supported by all arrays.
103
- class IArray a where
104
- -- | Return the length of an array.
105
- length :: a -> Int
106
-
107
- instance IArray Array where
108
- length = aLen
109
- {-# INLINE length #-}
110
-
111
- instance IArray (MArray s ) where
112
- length = maLen
113
- {-# INLINE length #-}
114
- #endif
74
+ data MArray s = MArray { maBA :: MutableByteArray # s }
115
75
116
76
-- | Create an uninitialized mutable array.
117
77
new :: forall s . Int -> ST s (MArray s )
118
78
new n
119
79
| n < 0 || n .&. highBit /= 0 = array_size_error
120
80
| otherwise = ST $ \ s1# ->
121
81
case newByteArray# len# s1# of
122
- (# s2# , marr# # ) -> (# s2# , MArray marr#
123
- #if defined(ASSERTS)
124
- n
125
- #endif
126
- # )
82
+ (# s2# , marr# # ) -> (# s2# , MArray marr# # )
127
83
where ! (I # len# ) = bytesInArray n
128
84
highBit = maxBound `xor` (maxBound `shiftR` 1 )
129
85
{-# INLINE new #-}
@@ -135,11 +91,7 @@ array_size_error = error "Data.Text.Array.new: size overflow"
135
91
unsafeFreeze :: MArray s -> ST s Array
136
92
unsafeFreeze MArray {.. } = ST $ \ s1# ->
137
93
case unsafeFreezeByteArray# maBA s1# of
138
- (# s2# , ba# # ) -> (# s2# , Array ba#
139
- #if defined(ASSERTS)
140
- maLen
141
- #endif
142
- # )
94
+ (# s2# , ba# # ) -> (# s2# , Array ba# # )
143
95
{-# INLINE unsafeFreeze #-}
144
96
145
97
-- | Indicate how many bytes would be used for an array of the given
@@ -151,16 +103,24 @@ bytesInArray n = n `shiftL` 1
151
103
-- | Unchecked read of an immutable array. May return garbage or
152
104
-- crash on an out-of-bounds access.
153
105
unsafeIndex :: Array -> Int -> Word16
154
- unsafeIndex Array {.. } i@ (I # i# ) =
155
- CHECK_BOUNDS (" unsafeIndex" ,aLen,i)
156
- case indexWord16Array# aBA i# of r# -> (W16 # r# )
106
+ unsafeIndex a@ Array {.. } i@ (I # i# ) =
107
+ #if defined(ASSERTS)
108
+ let word16len = I # (sizeofByteArray# aBA) `quot` 2 in
109
+ if i < 0 || i >= word16len
110
+ then error (" Data.Text.Array.unsafeIndex: bounds error, offset " ++ show i ++ " , length " ++ show word16len)
111
+ else
112
+ #endif
113
+ case indexWord16Array# aBA i# of r# -> (W16 # r# )
157
114
{-# INLINE unsafeIndex #-}
158
115
159
116
-- | Unchecked write of a mutable array. May return garbage or crash
160
117
-- on an out-of-bounds access.
161
118
unsafeWrite :: MArray s -> Int -> Word16 -> ST s ()
162
- unsafeWrite MArray {.. } i@ (I # i# ) (W16 # e# ) = ST $ \ s1# ->
163
- CHECK_BOUNDS (" unsafeWrite" ,maLen,i)
119
+ unsafeWrite ma@ MArray {.. } i@ (I # i# ) (W16 # e# ) = ST $ \ s1# ->
120
+ #if defined(ASSERTS)
121
+ let word16len = I # (sizeofMutableByteArray# maBA) `quot` 2 in
122
+ if i < 0 || i >= word16len then error (" Data.Text.Array.unsafeWrite: bounds error, offset " ++ show i ++ " , length " ++ show word16len) else
123
+ #endif
164
124
case writeWord16Array# maBA i# e# s1# of
165
125
s2# -> (# s2# , () # )
166
126
{-# INLINE unsafeWrite #-}
@@ -200,8 +160,8 @@ copyM dest didx src sidx count
200
160
| count <= 0 = return ()
201
161
| otherwise =
202
162
#if defined(ASSERTS)
203
- assert (sidx + count <= length src) .
204
- assert (didx + count <= length dest) .
163
+ assert (sidx + count <= I # (sizeofMutableByteArray # (maBA src)) `quot` 2 ) .
164
+ assert (didx + count <= I # (sizeofMutableByteArray # (maBA dest)) `quot` 2 ) .
205
165
#endif
206
166
unsafeIOToST $ memcpyM (maBA dest) (fromIntegral didx)
207
167
(maBA src) (fromIntegral sidx)
0 commit comments