SafeHaskell: Added SafeHaskell to base
[packages/base.git] / GHC / Word.hs
1 {-# LANGUAGE Trustworthy #-}
2 {-# LANGUAGE CPP, NoImplicitPrelude, BangPatterns, MagicHash #-}
3 {-# OPTIONS_HADDOCK hide #-}
4
5 -----------------------------------------------------------------------------
6 -- |
7 -- Module : GHC.Word
8 -- Copyright : (c) The University of Glasgow, 1997-2002
9 -- License : see libraries/base/LICENSE
10 --
11 -- Maintainer : cvs-ghc@haskell.org
12 -- Stability : internal
13 -- Portability : non-portable (GHC Extensions)
14 --
15 -- Sized unsigned integral types: 'Word', 'Word8', 'Word16', 'Word32', and
16 -- 'Word64'.
17 --
18 -----------------------------------------------------------------------------
19
20 #include "MachDeps.h"
21
22 -- #hide
23 module GHC.Word (
24 Word(..), Word8(..), Word16(..), Word32(..), Word64(..),
25 toEnumError, fromEnumError, succError, predError,
26 uncheckedShiftL64#,
27 uncheckedShiftRL64#
28 ) where
29
30 import Data.Bits
31
32 #if WORD_SIZE_IN_BITS < 32
33 import GHC.IntWord32
34 #endif
35 #if WORD_SIZE_IN_BITS < 64
36 import GHC.IntWord64
37 #endif
38
39 import GHC.Base
40 import GHC.Enum
41 import GHC.Num
42 import GHC.Real
43 import GHC.Read
44 import GHC.Arr
45 import GHC.Show
46 import GHC.Err
47 import GHC.Float () -- for RealFrac methods
48
49 ------------------------------------------------------------------------
50 -- Helper functions
51 ------------------------------------------------------------------------
52
53 {-# NOINLINE toEnumError #-}
54 toEnumError :: (Show a) => String -> Int -> (a,a) -> b
55 toEnumError inst_ty i bnds =
56 error $ "Enum.toEnum{" ++ inst_ty ++ "}: tag (" ++
57 show i ++
58 ") is outside of bounds " ++
59 show bnds
60
61 {-# NOINLINE fromEnumError #-}
62 fromEnumError :: (Show a) => String -> a -> b
63 fromEnumError inst_ty x =
64 error $ "Enum.fromEnum{" ++ inst_ty ++ "}: value (" ++
65 show x ++
66 ") is outside of Int's bounds " ++
67 show (minBound::Int, maxBound::Int)
68
69 {-# NOINLINE succError #-}
70 succError :: String -> a
71 succError inst_ty =
72 error $ "Enum.succ{" ++ inst_ty ++ "}: tried to take `succ' of maxBound"
73
74 {-# NOINLINE predError #-}
75 predError :: String -> a
76 predError inst_ty =
77 error $ "Enum.pred{" ++ inst_ty ++ "}: tried to take `pred' of minBound"
78
79 ------------------------------------------------------------------------
80 -- type Word
81 ------------------------------------------------------------------------
82
83 -- |A 'Word' is an unsigned integral type, with the same size as 'Int'.
84 data Word = W# Word# deriving (Eq, Ord)
85
86 instance Show Word where
87 showsPrec p x = showsPrec p (toInteger x)
88
89 instance Num Word where
90 (W# x#) + (W# y#) = W# (x# `plusWord#` y#)
91 (W# x#) - (W# y#) = W# (x# `minusWord#` y#)
92 (W# x#) * (W# y#) = W# (x# `timesWord#` y#)
93 negate (W# x#) = W# (int2Word# (negateInt# (word2Int# x#)))
94 abs x = x
95 signum 0 = 0
96 signum _ = 1
97 fromInteger i = W# (integerToWord i)
98
99 instance Real Word where
100 toRational x = toInteger x % 1
101
102 instance Enum Word where
103 succ x
104 | x /= maxBound = x + 1
105 | otherwise = succError "Word"
106 pred x
107 | x /= minBound = x - 1
108 | otherwise = predError "Word"
109 toEnum i@(I# i#)
110 | i >= 0 = W# (int2Word# i#)
111 | otherwise = toEnumError "Word" i (minBound::Word, maxBound::Word)
112 fromEnum x@(W# x#)
113 | x <= fromIntegral (maxBound::Int)
114 = I# (word2Int# x#)
115 | otherwise = fromEnumError "Word" x
116 enumFrom = integralEnumFrom
117 enumFromThen = integralEnumFromThen
118 enumFromTo = integralEnumFromTo
119 enumFromThenTo = integralEnumFromThenTo
120
121 instance Integral Word where
122 quot (W# x#) y@(W# y#)
123 | y /= 0 = W# (x# `quotWord#` y#)
124 | otherwise = divZeroError
125 rem (W# x#) y@(W# y#)
126 | y /= 0 = W# (x# `remWord#` y#)
127 | otherwise = divZeroError
128 div (W# x#) y@(W# y#)
129 | y /= 0 = W# (x# `quotWord#` y#)
130 | otherwise = divZeroError
131 mod (W# x#) y@(W# y#)
132 | y /= 0 = W# (x# `remWord#` y#)
133 | otherwise = divZeroError
134 quotRem (W# x#) y@(W# y#)
135 | y /= 0 = (W# (x# `quotWord#` y#), W# (x# `remWord#` y#))
136 | otherwise = divZeroError
137 divMod (W# x#) y@(W# y#)
138 | y /= 0 = (W# (x# `quotWord#` y#), W# (x# `remWord#` y#))
139 | otherwise = divZeroError
140 toInteger (W# x#)
141 | i# >=# 0# = smallInteger i#
142 | otherwise = wordToInteger x#
143 where
144 !i# = word2Int# x#
145
146 instance Bounded Word where
147 minBound = 0
148
149 -- use unboxed literals for maxBound, because GHC doesn't optimise
150 -- (fromInteger 0xffffffff :: Word).
151 #if WORD_SIZE_IN_BITS == 31
152 maxBound = W# (int2Word# 0x7FFFFFFF#)
153 #elif WORD_SIZE_IN_BITS == 32
154 maxBound = W# (int2Word# 0xFFFFFFFF#)
155 #else
156 maxBound = W# (int2Word# 0xFFFFFFFFFFFFFFFF#)
157 #endif
158
159 instance Ix Word where
160 range (m,n) = [m..n]
161 unsafeIndex (m,_) i = fromIntegral (i - m)
162 inRange (m,n) i = m <= i && i <= n
163
164 instance Read Word where
165 readsPrec p s = [(fromInteger x, r) | (x, r) <- readsPrec p s]
166
167 instance Bits Word where
168 {-# INLINE shift #-}
169
170 (W# x#) .&. (W# y#) = W# (x# `and#` y#)
171 (W# x#) .|. (W# y#) = W# (x# `or#` y#)
172 (W# x#) `xor` (W# y#) = W# (x# `xor#` y#)
173 complement (W# x#) = W# (x# `xor#` mb#)
174 where !(W# mb#) = maxBound
175 (W# x#) `shift` (I# i#)
176 | i# >=# 0# = W# (x# `shiftL#` i#)
177 | otherwise = W# (x# `shiftRL#` negateInt# i#)
178 (W# x#) `rotate` (I# i#)
179 | i'# ==# 0# = W# x#
180 | otherwise = W# ((x# `uncheckedShiftL#` i'#) `or#` (x# `uncheckedShiftRL#` (wsib -# i'#)))
181 where
182 !i'# = word2Int# (int2Word# i# `and#` int2Word# (wsib -# 1#))
183 !wsib = WORD_SIZE_IN_BITS# {- work around preprocessor problem (??) -}
184 bitSize _ = WORD_SIZE_IN_BITS
185 isSigned _ = False
186
187 {-# RULES
188 "fromIntegral/Int->Word" fromIntegral = \(I# x#) -> W# (int2Word# x#)
189 "fromIntegral/Word->Int" fromIntegral = \(W# x#) -> I# (word2Int# x#)
190 "fromIntegral/Word->Word" fromIntegral = id :: Word -> Word
191 #-}
192
193 -- No RULES for RealFrac unfortunately.
194 -- Going through Int isn't possible because Word's range is not
195 -- included in Int's, going through Integer may or may not be slower.
196
197 ------------------------------------------------------------------------
198 -- type Word8
199 ------------------------------------------------------------------------
200
201 -- Word8 is represented in the same way as Word. Operations may assume
202 -- and must ensure that it holds only values from its logical range.
203
204 data Word8 = W8# Word# deriving (Eq, Ord)
205 -- ^ 8-bit unsigned integer type
206
207 instance Show Word8 where
208 showsPrec p x = showsPrec p (fromIntegral x :: Int)
209
210 instance Num Word8 where
211 (W8# x#) + (W8# y#) = W8# (narrow8Word# (x# `plusWord#` y#))
212 (W8# x#) - (W8# y#) = W8# (narrow8Word# (x# `minusWord#` y#))
213 (W8# x#) * (W8# y#) = W8# (narrow8Word# (x# `timesWord#` y#))
214 negate (W8# x#) = W8# (narrow8Word# (int2Word# (negateInt# (word2Int# x#))))
215 abs x = x
216 signum 0 = 0
217 signum _ = 1
218 fromInteger i = W8# (narrow8Word# (integerToWord i))
219
220 instance Real Word8 where
221 toRational x = toInteger x % 1
222
223 instance Enum Word8 where
224 succ x
225 | x /= maxBound = x + 1
226 | otherwise = succError "Word8"
227 pred x
228 | x /= minBound = x - 1
229 | otherwise = predError "Word8"
230 toEnum i@(I# i#)
231 | i >= 0 && i <= fromIntegral (maxBound::Word8)
232 = W8# (int2Word# i#)
233 | otherwise = toEnumError "Word8" i (minBound::Word8, maxBound::Word8)
234 fromEnum (W8# x#) = I# (word2Int# x#)
235 enumFrom = boundedEnumFrom
236 enumFromThen = boundedEnumFromThen
237
238 instance Integral Word8 where
239 quot (W8# x#) y@(W8# y#)
240 | y /= 0 = W8# (x# `quotWord#` y#)
241 | otherwise = divZeroError
242 rem (W8# x#) y@(W8# y#)
243 | y /= 0 = W8# (x# `remWord#` y#)
244 | otherwise = divZeroError
245 div (W8# x#) y@(W8# y#)
246 | y /= 0 = W8# (x# `quotWord#` y#)
247 | otherwise = divZeroError
248 mod (W8# x#) y@(W8# y#)
249 | y /= 0 = W8# (x# `remWord#` y#)
250 | otherwise = divZeroError
251 quotRem (W8# x#) y@(W8# y#)
252 | y /= 0 = (W8# (x# `quotWord#` y#), W8# (x# `remWord#` y#))
253 | otherwise = divZeroError
254 divMod (W8# x#) y@(W8# y#)
255 | y /= 0 = (W8# (x# `quotWord#` y#), W8# (x# `remWord#` y#))
256 | otherwise = divZeroError
257 toInteger (W8# x#) = smallInteger (word2Int# x#)
258
259 instance Bounded Word8 where
260 minBound = 0
261 maxBound = 0xFF
262
263 instance Ix Word8 where
264 range (m,n) = [m..n]
265 unsafeIndex (m,_) i = fromIntegral (i - m)
266 inRange (m,n) i = m <= i && i <= n
267
268 instance Read Word8 where
269 readsPrec p s = [(fromIntegral (x::Int), r) | (x, r) <- readsPrec p s]
270
271 instance Bits Word8 where
272 {-# INLINE shift #-}
273
274 (W8# x#) .&. (W8# y#) = W8# (x# `and#` y#)
275 (W8# x#) .|. (W8# y#) = W8# (x# `or#` y#)
276 (W8# x#) `xor` (W8# y#) = W8# (x# `xor#` y#)
277 complement (W8# x#) = W8# (x# `xor#` mb#)
278 where !(W8# mb#) = maxBound
279 (W8# x#) `shift` (I# i#)
280 | i# >=# 0# = W8# (narrow8Word# (x# `shiftL#` i#))
281 | otherwise = W8# (x# `shiftRL#` negateInt# i#)
282 (W8# x#) `rotate` (I# i#)
283 | i'# ==# 0# = W8# x#
284 | otherwise = W8# (narrow8Word# ((x# `uncheckedShiftL#` i'#) `or#`
285 (x# `uncheckedShiftRL#` (8# -# i'#))))
286 where
287 !i'# = word2Int# (int2Word# i# `and#` int2Word# 7#)
288 bitSize _ = 8
289 isSigned _ = False
290
291 {-# RULES
292 "fromIntegral/Word8->Word8" fromIntegral = id :: Word8 -> Word8
293 "fromIntegral/Word8->Integer" fromIntegral = toInteger :: Word8 -> Integer
294 "fromIntegral/a->Word8" fromIntegral = \x -> case fromIntegral x of W# x# -> W8# (narrow8Word# x#)
295 "fromIntegral/Word8->a" fromIntegral = \(W8# x#) -> fromIntegral (W# x#)
296 #-}
297
298 {-# RULES
299 "properFraction/Float->(Word8,Float)"
300 forall x. properFraction (x :: Float) =
301 case properFraction x of {
302 (n, y) -> ((fromIntegral :: Int -> Word8) n, y) }
303 "truncate/Float->Word8"
304 forall x. truncate (x :: Float) = (fromIntegral :: Int -> Word8) (truncate x)
305 "floor/Float->Word8"
306 forall x. floor (x :: Float) = (fromIntegral :: Int -> Word8) (floor x)
307 "ceiling/Float->Word8"
308 forall x. ceiling (x :: Float) = (fromIntegral :: Int -> Word8) (ceiling x)
309 "round/Float->Word8"
310 forall x. round (x :: Float) = (fromIntegral :: Int -> Word8) (round x)
311 #-}
312
313 {-# RULES
314 "properFraction/Double->(Word8,Double)"
315 forall x. properFraction (x :: Double) =
316 case properFraction x of {
317 (n, y) -> ((fromIntegral :: Int -> Word8) n, y) }
318 "truncate/Double->Word8"
319 forall x. truncate (x :: Double) = (fromIntegral :: Int -> Word8) (truncate x)
320 "floor/Double->Word8"
321 forall x. floor (x :: Double) = (fromIntegral :: Int -> Word8) (floor x)
322 "ceiling/Double->Word8"
323 forall x. ceiling (x :: Double) = (fromIntegral :: Int -> Word8) (ceiling x)
324 "round/Double->Word8"
325 forall x. round (x :: Double) = (fromIntegral :: Int -> Word8) (round x)
326 #-}
327
328 ------------------------------------------------------------------------
329 -- type Word16
330 ------------------------------------------------------------------------
331
332 -- Word16 is represented in the same way as Word. Operations may assume
333 -- and must ensure that it holds only values from its logical range.
334
335 data Word16 = W16# Word# deriving (Eq, Ord)
336 -- ^ 16-bit unsigned integer type
337
338 instance Show Word16 where
339 showsPrec p x = showsPrec p (fromIntegral x :: Int)
340
341 instance Num Word16 where
342 (W16# x#) + (W16# y#) = W16# (narrow16Word# (x# `plusWord#` y#))
343 (W16# x#) - (W16# y#) = W16# (narrow16Word# (x# `minusWord#` y#))
344 (W16# x#) * (W16# y#) = W16# (narrow16Word# (x# `timesWord#` y#))
345 negate (W16# x#) = W16# (narrow16Word# (int2Word# (negateInt# (word2Int# x#))))
346 abs x = x
347 signum 0 = 0
348 signum _ = 1
349 fromInteger i = W16# (narrow16Word# (integerToWord i))
350
351 instance Real Word16 where
352 toRational x = toInteger x % 1
353
354 instance Enum Word16 where
355 succ x
356 | x /= maxBound = x + 1
357 | otherwise = succError "Word16"
358 pred x
359 | x /= minBound = x - 1
360 | otherwise = predError "Word16"
361 toEnum i@(I# i#)
362 | i >= 0 && i <= fromIntegral (maxBound::Word16)
363 = W16# (int2Word# i#)
364 | otherwise = toEnumError "Word16" i (minBound::Word16, maxBound::Word16)
365 fromEnum (W16# x#) = I# (word2Int# x#)
366 enumFrom = boundedEnumFrom
367 enumFromThen = boundedEnumFromThen
368
369 instance Integral Word16 where
370 quot (W16# x#) y@(W16# y#)
371 | y /= 0 = W16# (x# `quotWord#` y#)
372 | otherwise = divZeroError
373 rem (W16# x#) y@(W16# y#)
374 | y /= 0 = W16# (x# `remWord#` y#)
375 | otherwise = divZeroError
376 div (W16# x#) y@(W16# y#)
377 | y /= 0 = W16# (x# `quotWord#` y#)
378 | otherwise = divZeroError
379 mod (W16# x#) y@(W16# y#)
380 | y /= 0 = W16# (x# `remWord#` y#)
381 | otherwise = divZeroError
382 quotRem (W16# x#) y@(W16# y#)
383 | y /= 0 = (W16# (x# `quotWord#` y#), W16# (x# `remWord#` y#))
384 | otherwise = divZeroError
385 divMod (W16# x#) y@(W16# y#)
386 | y /= 0 = (W16# (x# `quotWord#` y#), W16# (x# `remWord#` y#))
387 | otherwise = divZeroError
388 toInteger (W16# x#) = smallInteger (word2Int# x#)
389
390 instance Bounded Word16 where
391 minBound = 0
392 maxBound = 0xFFFF
393
394 instance Ix Word16 where
395 range (m,n) = [m..n]
396 unsafeIndex (m,_) i = fromIntegral (i - m)
397 inRange (m,n) i = m <= i && i <= n
398
399 instance Read Word16 where
400 readsPrec p s = [(fromIntegral (x::Int), r) | (x, r) <- readsPrec p s]
401
402 instance Bits Word16 where
403 {-# INLINE shift #-}
404
405 (W16# x#) .&. (W16# y#) = W16# (x# `and#` y#)
406 (W16# x#) .|. (W16# y#) = W16# (x# `or#` y#)
407 (W16# x#) `xor` (W16# y#) = W16# (x# `xor#` y#)
408 complement (W16# x#) = W16# (x# `xor#` mb#)
409 where !(W16# mb#) = maxBound
410 (W16# x#) `shift` (I# i#)
411 | i# >=# 0# = W16# (narrow16Word# (x# `shiftL#` i#))
412 | otherwise = W16# (x# `shiftRL#` negateInt# i#)
413 (W16# x#) `rotate` (I# i#)
414 | i'# ==# 0# = W16# x#
415 | otherwise = W16# (narrow16Word# ((x# `uncheckedShiftL#` i'#) `or#`
416 (x# `uncheckedShiftRL#` (16# -# i'#))))
417 where
418 !i'# = word2Int# (int2Word# i# `and#` int2Word# 15#)
419 bitSize _ = 16
420 isSigned _ = False
421
422 {-# RULES
423 "fromIntegral/Word8->Word16" fromIntegral = \(W8# x#) -> W16# x#
424 "fromIntegral/Word16->Word16" fromIntegral = id :: Word16 -> Word16
425 "fromIntegral/Word16->Integer" fromIntegral = toInteger :: Word16 -> Integer
426 "fromIntegral/a->Word16" fromIntegral = \x -> case fromIntegral x of W# x# -> W16# (narrow16Word# x#)
427 "fromIntegral/Word16->a" fromIntegral = \(W16# x#) -> fromIntegral (W# x#)
428 #-}
429
430 {-# RULES
431 "properFraction/Float->(Word16,Float)"
432 forall x. properFraction (x :: Float) =
433 case properFraction x of {
434 (n, y) -> ((fromIntegral :: Int -> Word16) n, y) }
435 "truncate/Float->Word16"
436 forall x. truncate (x :: Float) = (fromIntegral :: Int -> Word16) (truncate x)
437 "floor/Float->Word16"
438 forall x. floor (x :: Float) = (fromIntegral :: Int -> Word16) (floor x)
439 "ceiling/Float->Word16"
440 forall x. ceiling (x :: Float) = (fromIntegral :: Int -> Word16) (ceiling x)
441 "round/Float->Word16"
442 forall x. round (x :: Float) = (fromIntegral :: Int -> Word16) (round x)
443 #-}
444
445 {-# RULES
446 "properFraction/Double->(Word16,Double)"
447 forall x. properFraction (x :: Double) =
448 case properFraction x of {
449 (n, y) -> ((fromIntegral :: Int -> Word16) n, y) }
450 "truncate/Double->Word16"
451 forall x. truncate (x :: Double) = (fromIntegral :: Int -> Word16) (truncate x)
452 "floor/Double->Word16"
453 forall x. floor (x :: Double) = (fromIntegral :: Int -> Word16) (floor x)
454 "ceiling/Double->Word16"
455 forall x. ceiling (x :: Double) = (fromIntegral :: Int -> Word16) (ceiling x)
456 "round/Double->Word16"
457 forall x. round (x :: Double) = (fromIntegral :: Int -> Word16) (round x)
458 #-}
459
460 ------------------------------------------------------------------------
461 -- type Word32
462 ------------------------------------------------------------------------
463
464 #if WORD_SIZE_IN_BITS < 32
465
466 data Word32 = W32# Word32#
467 -- ^ 32-bit unsigned integer type
468
469 instance Eq Word32 where
470 (W32# x#) == (W32# y#) = x# `eqWord32#` y#
471 (W32# x#) /= (W32# y#) = x# `neWord32#` y#
472
473 instance Ord Word32 where
474 (W32# x#) < (W32# y#) = x# `ltWord32#` y#
475 (W32# x#) <= (W32# y#) = x# `leWord32#` y#
476 (W32# x#) > (W32# y#) = x# `gtWord32#` y#
477 (W32# x#) >= (W32# y#) = x# `geWord32#` y#
478
479 instance Num Word32 where
480 (W32# x#) + (W32# y#) = W32# (int32ToWord32# (word32ToInt32# x# `plusInt32#` word32ToInt32# y#))
481 (W32# x#) - (W32# y#) = W32# (int32ToWord32# (word32ToInt32# x# `minusInt32#` word32ToInt32# y#))
482 (W32# x#) * (W32# y#) = W32# (int32ToWord32# (word32ToInt32# x# `timesInt32#` word32ToInt32# y#))
483 negate (W32# x#) = W32# (int32ToWord32# (negateInt32# (word32ToInt32# x#)))
484 abs x = x
485 signum 0 = 0
486 signum _ = 1
487 fromInteger (S# i#) = W32# (int32ToWord32# (intToInt32# i#))
488 fromInteger (J# s# d#) = W32# (integerToWord32# s# d#)
489
490 instance Enum Word32 where
491 succ x
492 | x /= maxBound = x + 1
493 | otherwise = succError "Word32"
494 pred x
495 | x /= minBound = x - 1
496 | otherwise = predError "Word32"
497 toEnum i@(I# i#)
498 | i >= 0 = W32# (wordToWord32# (int2Word# i#))
499 | otherwise = toEnumError "Word32" i (minBound::Word32, maxBound::Word32)
500 fromEnum x@(W32# x#)
501 | x <= fromIntegral (maxBound::Int)
502 = I# (word2Int# (word32ToWord# x#))
503 | otherwise = fromEnumError "Word32" x
504 enumFrom = integralEnumFrom
505 enumFromThen = integralEnumFromThen
506 enumFromTo = integralEnumFromTo
507 enumFromThenTo = integralEnumFromThenTo
508
509 instance Integral Word32 where
510 quot x@(W32# x#) y@(W32# y#)
511 | y /= 0 = W32# (x# `quotWord32#` y#)
512 | otherwise = divZeroError
513 rem x@(W32# x#) y@(W32# y#)
514 | y /= 0 = W32# (x# `remWord32#` y#)
515 | otherwise = divZeroError
516 div x@(W32# x#) y@(W32# y#)
517 | y /= 0 = W32# (x# `quotWord32#` y#)
518 | otherwise = divZeroError
519 mod x@(W32# x#) y@(W32# y#)
520 | y /= 0 = W32# (x# `remWord32#` y#)
521 | otherwise = divZeroError
522 quotRem x@(W32# x#) y@(W32# y#)
523 | y /= 0 = (W32# (x# `quotWord32#` y#), W32# (x# `remWord32#` y#))
524 | otherwise = divZeroError
525 divMod x@(W32# x#) y@(W32# y#)
526 | y /= 0 = (W32# (x# `quotWord32#` y#), W32# (x# `remWord32#` y#))
527 | otherwise = divZeroError
528 toInteger x@(W32# x#)
529 | x <= fromIntegral (maxBound::Int) = S# (word2Int# (word32ToWord# x#))
530 | otherwise = case word32ToInteger# x# of (# s, d #) -> J# s d
531
532 instance Bits Word32 where
533 {-# INLINE shift #-}
534
535 (W32# x#) .&. (W32# y#) = W32# (x# `and32#` y#)
536 (W32# x#) .|. (W32# y#) = W32# (x# `or32#` y#)
537 (W32# x#) `xor` (W32# y#) = W32# (x# `xor32#` y#)
538 complement (W32# x#) = W32# (not32# x#)
539 (W32# x#) `shift` (I# i#)
540 | i# >=# 0# = W32# (x# `shiftL32#` i#)
541 | otherwise = W32# (x# `shiftRL32#` negateInt# i#)
542 (W32# x#) `rotate` (I# i#)
543 | i'# ==# 0# = W32# x#
544 | otherwise = W32# ((x# `shiftL32#` i'#) `or32#`
545 (x# `shiftRL32#` (32# -# i'#)))
546 where
547 i'# = word2Int# (int2Word# i# `and#` int2Word# 31#)
548 bitSize _ = 32
549 isSigned _ = False
550
551 {-# RULES
552 "fromIntegral/Int->Word32" fromIntegral = \(I# x#) -> W32# (int32ToWord32# (intToInt32# x#))
553 "fromIntegral/Word->Word32" fromIntegral = \(W# x#) -> W32# (wordToWord32# x#)
554 "fromIntegral/Word32->Int" fromIntegral = \(W32# x#) -> I# (word2Int# (word32ToWord# x#))
555 "fromIntegral/Word32->Word" fromIntegral = \(W32# x#) -> W# (word32ToWord# x#)
556 "fromIntegral/Word32->Word32" fromIntegral = id :: Word32 -> Word32
557 #-}
558
559 #else
560
561 -- Word32 is represented in the same way as Word.
562 #if WORD_SIZE_IN_BITS > 32
563 -- Operations may assume and must ensure that it holds only values
564 -- from its logical range.
565
566 -- We can use rewrite rules for the RealFrac methods
567
568 {-# RULES
569 "properFraction/Float->(Word32,Float)"
570 forall x. properFraction (x :: Float) =
571 case properFraction x of {
572 (n, y) -> ((fromIntegral :: Int -> Word32) n, y) }
573 "truncate/Float->Word32"
574 forall x. truncate (x :: Float) = (fromIntegral :: Int -> Word32) (truncate x)
575 "floor/Float->Word32"
576 forall x. floor (x :: Float) = (fromIntegral :: Int -> Word32) (floor x)
577 "ceiling/Float->Word32"
578 forall x. ceiling (x :: Float) = (fromIntegral :: Int -> Word32) (ceiling x)
579 "round/Float->Word32"
580 forall x. round (x :: Float) = (fromIntegral :: Int -> Word32) (round x)
581 #-}
582
583 {-# RULES
584 "properFraction/Double->(Word32,Double)"
585 forall x. properFraction (x :: Double) =
586 case properFraction x of {
587 (n, y) -> ((fromIntegral :: Int -> Word32) n, y) }
588 "truncate/Double->Word32"
589 forall x. truncate (x :: Double) = (fromIntegral :: Int -> Word32) (truncate x)
590 "floor/Double->Word32"
591 forall x. floor (x :: Double) = (fromIntegral :: Int -> Word32) (floor x)
592 "ceiling/Double->Word32"
593 forall x. ceiling (x :: Double) = (fromIntegral :: Int -> Word32) (ceiling x)
594 "round/Double->Word32"
595 forall x. round (x :: Double) = (fromIntegral :: Int -> Word32) (round x)
596 #-}
597
598 #endif
599
600 data Word32 = W32# Word# deriving (Eq, Ord)
601 -- ^ 32-bit unsigned integer type
602
603 instance Num Word32 where
604 (W32# x#) + (W32# y#) = W32# (narrow32Word# (x# `plusWord#` y#))
605 (W32# x#) - (W32# y#) = W32# (narrow32Word# (x# `minusWord#` y#))
606 (W32# x#) * (W32# y#) = W32# (narrow32Word# (x# `timesWord#` y#))
607 negate (W32# x#) = W32# (narrow32Word# (int2Word# (negateInt# (word2Int# x#))))
608 abs x = x
609 signum 0 = 0
610 signum _ = 1
611 fromInteger i = W32# (narrow32Word# (integerToWord i))
612
613 instance Enum Word32 where
614 succ x
615 | x /= maxBound = x + 1
616 | otherwise = succError "Word32"
617 pred x
618 | x /= minBound = x - 1
619 | otherwise = predError "Word32"
620 toEnum i@(I# i#)
621 | i >= 0
622 #if WORD_SIZE_IN_BITS > 32
623 && i <= fromIntegral (maxBound::Word32)
624 #endif
625 = W32# (int2Word# i#)
626 | otherwise = toEnumError "Word32" i (minBound::Word32, maxBound::Word32)
627 #if WORD_SIZE_IN_BITS == 32
628 fromEnum x@(W32# x#)
629 | x <= fromIntegral (maxBound::Int)
630 = I# (word2Int# x#)
631 | otherwise = fromEnumError "Word32" x
632 enumFrom = integralEnumFrom
633 enumFromThen = integralEnumFromThen
634 enumFromTo = integralEnumFromTo
635 enumFromThenTo = integralEnumFromThenTo
636 #else
637 fromEnum (W32# x#) = I# (word2Int# x#)
638 enumFrom = boundedEnumFrom
639 enumFromThen = boundedEnumFromThen
640 #endif
641
642 instance Integral Word32 where
643 quot (W32# x#) y@(W32# y#)
644 | y /= 0 = W32# (x# `quotWord#` y#)
645 | otherwise = divZeroError
646 rem (W32# x#) y@(W32# y#)
647 | y /= 0 = W32# (x# `remWord#` y#)
648 | otherwise = divZeroError
649 div (W32# x#) y@(W32# y#)
650 | y /= 0 = W32# (x# `quotWord#` y#)
651 | otherwise = divZeroError
652 mod (W32# x#) y@(W32# y#)
653 | y /= 0 = W32# (x# `remWord#` y#)
654 | otherwise = divZeroError
655 quotRem (W32# x#) y@(W32# y#)
656 | y /= 0 = (W32# (x# `quotWord#` y#), W32# (x# `remWord#` y#))
657 | otherwise = divZeroError
658 divMod (W32# x#) y@(W32# y#)
659 | y /= 0 = (W32# (x# `quotWord#` y#), W32# (x# `remWord#` y#))
660 | otherwise = divZeroError
661 toInteger (W32# x#)
662 #if WORD_SIZE_IN_BITS == 32
663 | i# >=# 0# = smallInteger i#
664 | otherwise = wordToInteger x#
665 where
666 !i# = word2Int# x#
667 #else
668 = smallInteger (word2Int# x#)
669 #endif
670
671 instance Bits Word32 where
672 {-# INLINE shift #-}
673
674 (W32# x#) .&. (W32# y#) = W32# (x# `and#` y#)
675 (W32# x#) .|. (W32# y#) = W32# (x# `or#` y#)
676 (W32# x#) `xor` (W32# y#) = W32# (x# `xor#` y#)
677 complement (W32# x#) = W32# (x# `xor#` mb#)
678 where !(W32# mb#) = maxBound
679 (W32# x#) `shift` (I# i#)
680 | i# >=# 0# = W32# (narrow32Word# (x# `shiftL#` i#))
681 | otherwise = W32# (x# `shiftRL#` negateInt# i#)
682 (W32# x#) `rotate` (I# i#)
683 | i'# ==# 0# = W32# x#
684 | otherwise = W32# (narrow32Word# ((x# `uncheckedShiftL#` i'#) `or#`
685 (x# `uncheckedShiftRL#` (32# -# i'#))))
686 where
687 !i'# = word2Int# (int2Word# i# `and#` int2Word# 31#)
688 bitSize _ = 32
689 isSigned _ = False
690
691 {-# RULES
692 "fromIntegral/Word8->Word32" fromIntegral = \(W8# x#) -> W32# x#
693 "fromIntegral/Word16->Word32" fromIntegral = \(W16# x#) -> W32# x#
694 "fromIntegral/Word32->Word32" fromIntegral = id :: Word32 -> Word32
695 "fromIntegral/Word32->Integer" fromIntegral = toInteger :: Word32 -> Integer
696 "fromIntegral/a->Word32" fromIntegral = \x -> case fromIntegral x of W# x# -> W32# (narrow32Word# x#)
697 "fromIntegral/Word32->a" fromIntegral = \(W32# x#) -> fromIntegral (W# x#)
698 #-}
699
700 #endif
701
702 instance Show Word32 where
703 #if WORD_SIZE_IN_BITS < 33
704 showsPrec p x = showsPrec p (toInteger x)
705 #else
706 showsPrec p x = showsPrec p (fromIntegral x :: Int)
707 #endif
708
709
710 instance Real Word32 where
711 toRational x = toInteger x % 1
712
713 instance Bounded Word32 where
714 minBound = 0
715 maxBound = 0xFFFFFFFF
716
717 instance Ix Word32 where
718 range (m,n) = [m..n]
719 unsafeIndex (m,_) i = fromIntegral (i - m)
720 inRange (m,n) i = m <= i && i <= n
721
722 instance Read Word32 where
723 #if WORD_SIZE_IN_BITS < 33
724 readsPrec p s = [(fromInteger x, r) | (x, r) <- readsPrec p s]
725 #else
726 readsPrec p s = [(fromIntegral (x::Int), r) | (x, r) <- readsPrec p s]
727 #endif
728
729 ------------------------------------------------------------------------
730 -- type Word64
731 ------------------------------------------------------------------------
732
733 #if WORD_SIZE_IN_BITS < 64
734
735 data Word64 = W64# Word64#
736 -- ^ 64-bit unsigned integer type
737
738 instance Eq Word64 where
739 (W64# x#) == (W64# y#) = x# `eqWord64#` y#
740 (W64# x#) /= (W64# y#) = x# `neWord64#` y#
741
742 instance Ord Word64 where
743 (W64# x#) < (W64# y#) = x# `ltWord64#` y#
744 (W64# x#) <= (W64# y#) = x# `leWord64#` y#
745 (W64# x#) > (W64# y#) = x# `gtWord64#` y#
746 (W64# x#) >= (W64# y#) = x# `geWord64#` y#
747
748 instance Num Word64 where
749 (W64# x#) + (W64# y#) = W64# (int64ToWord64# (word64ToInt64# x# `plusInt64#` word64ToInt64# y#))
750 (W64# x#) - (W64# y#) = W64# (int64ToWord64# (word64ToInt64# x# `minusInt64#` word64ToInt64# y#))
751 (W64# x#) * (W64# y#) = W64# (int64ToWord64# (word64ToInt64# x# `timesInt64#` word64ToInt64# y#))
752 negate (W64# x#) = W64# (int64ToWord64# (negateInt64# (word64ToInt64# x#)))
753 abs x = x
754 signum 0 = 0
755 signum _ = 1
756 fromInteger i = W64# (integerToWord64 i)
757
758 instance Enum Word64 where
759 succ x
760 | x /= maxBound = x + 1
761 | otherwise = succError "Word64"
762 pred x
763 | x /= minBound = x - 1
764 | otherwise = predError "Word64"
765 toEnum i@(I# i#)
766 | i >= 0 = W64# (wordToWord64# (int2Word# i#))
767 | otherwise = toEnumError "Word64" i (minBound::Word64, maxBound::Word64)
768 fromEnum x@(W64# x#)
769 | x <= fromIntegral (maxBound::Int)
770 = I# (word2Int# (word64ToWord# x#))
771 | otherwise = fromEnumError "Word64" x
772 enumFrom = integralEnumFrom
773 enumFromThen = integralEnumFromThen
774 enumFromTo = integralEnumFromTo
775 enumFromThenTo = integralEnumFromThenTo
776
777 instance Integral Word64 where
778 quot (W64# x#) y@(W64# y#)
779 | y /= 0 = W64# (x# `quotWord64#` y#)
780 | otherwise = divZeroError
781 rem (W64# x#) y@(W64# y#)
782 | y /= 0 = W64# (x# `remWord64#` y#)
783 | otherwise = divZeroError
784 div (W64# x#) y@(W64# y#)
785 | y /= 0 = W64# (x# `quotWord64#` y#)
786 | otherwise = divZeroError
787 mod (W64# x#) y@(W64# y#)
788 | y /= 0 = W64# (x# `remWord64#` y#)
789 | otherwise = divZeroError
790 quotRem (W64# x#) y@(W64# y#)
791 | y /= 0 = (W64# (x# `quotWord64#` y#), W64# (x# `remWord64#` y#))
792 | otherwise = divZeroError
793 divMod (W64# x#) y@(W64# y#)
794 | y /= 0 = (W64# (x# `quotWord64#` y#), W64# (x# `remWord64#` y#))
795 | otherwise = divZeroError
796 toInteger (W64# x#) = word64ToInteger x#
797
798 instance Bits Word64 where
799 {-# INLINE shift #-}
800
801 (W64# x#) .&. (W64# y#) = W64# (x# `and64#` y#)
802 (W64# x#) .|. (W64# y#) = W64# (x# `or64#` y#)
803 (W64# x#) `xor` (W64# y#) = W64# (x# `xor64#` y#)
804 complement (W64# x#) = W64# (not64# x#)
805 (W64# x#) `shift` (I# i#)
806 | i# >=# 0# = W64# (x# `shiftL64#` i#)
807 | otherwise = W64# (x# `shiftRL64#` negateInt# i#)
808 (W64# x#) `rotate` (I# i#)
809 | i'# ==# 0# = W64# x#
810 | otherwise = W64# ((x# `uncheckedShiftL64#` i'#) `or64#`
811 (x# `uncheckedShiftRL64#` (64# -# i'#)))
812 where
813 !i'# = word2Int# (int2Word# i# `and#` int2Word# 63#)
814 bitSize _ = 64
815 isSigned _ = False
816
817 -- give the 64-bit shift operations the same treatment as the 32-bit
818 -- ones (see GHC.Base), namely we wrap them in tests to catch the
819 -- cases when we're shifting more than 64 bits to avoid unspecified
820 -- behaviour in the C shift operations.
821
822 shiftL64#, shiftRL64# :: Word64# -> Int# -> Word64#
823
824 a `shiftL64#` b | b >=# 64# = wordToWord64# (int2Word# 0#)
825 | otherwise = a `uncheckedShiftL64#` b
826
827 a `shiftRL64#` b | b >=# 64# = wordToWord64# (int2Word# 0#)
828 | otherwise = a `uncheckedShiftRL64#` b
829
830 {-# RULES
831 "fromIntegral/Int->Word64" fromIntegral = \(I# x#) -> W64# (int64ToWord64# (intToInt64# x#))
832 "fromIntegral/Word->Word64" fromIntegral = \(W# x#) -> W64# (wordToWord64# x#)
833 "fromIntegral/Word64->Int" fromIntegral = \(W64# x#) -> I# (word2Int# (word64ToWord# x#))
834 "fromIntegral/Word64->Word" fromIntegral = \(W64# x#) -> W# (word64ToWord# x#)
835 "fromIntegral/Word64->Word64" fromIntegral = id :: Word64 -> Word64
836 #-}
837
838 #else
839
840 -- Word64 is represented in the same way as Word.
841 -- Operations may assume and must ensure that it holds only values
842 -- from its logical range.
843
844 data Word64 = W64# Word# deriving (Eq, Ord)
845 -- ^ 64-bit unsigned integer type
846
847 instance Num Word64 where
848 (W64# x#) + (W64# y#) = W64# (x# `plusWord#` y#)
849 (W64# x#) - (W64# y#) = W64# (x# `minusWord#` y#)
850 (W64# x#) * (W64# y#) = W64# (x# `timesWord#` y#)
851 negate (W64# x#) = W64# (int2Word# (negateInt# (word2Int# x#)))
852 abs x = x
853 signum 0 = 0
854 signum _ = 1
855 fromInteger i = W64# (integerToWord i)
856
857 instance Enum Word64 where
858 succ x
859 | x /= maxBound = x + 1
860 | otherwise = succError "Word64"
861 pred x
862 | x /= minBound = x - 1
863 | otherwise = predError "Word64"
864 toEnum i@(I# i#)
865 | i >= 0 = W64# (int2Word# i#)
866 | otherwise = toEnumError "Word64" i (minBound::Word64, maxBound::Word64)
867 fromEnum x@(W64# x#)
868 | x <= fromIntegral (maxBound::Int)
869 = I# (word2Int# x#)
870 | otherwise = fromEnumError "Word64" x
871 enumFrom = integralEnumFrom
872 enumFromThen = integralEnumFromThen
873 enumFromTo = integralEnumFromTo
874 enumFromThenTo = integralEnumFromThenTo
875
876 instance Integral Word64 where
877 quot (W64# x#) y@(W64# y#)
878 | y /= 0 = W64# (x# `quotWord#` y#)
879 | otherwise = divZeroError
880 rem (W64# x#) y@(W64# y#)
881 | y /= 0 = W64# (x# `remWord#` y#)
882 | otherwise = divZeroError
883 div (W64# x#) y@(W64# y#)
884 | y /= 0 = W64# (x# `quotWord#` y#)
885 | otherwise = divZeroError
886 mod (W64# x#) y@(W64# y#)
887 | y /= 0 = W64# (x# `remWord#` y#)
888 | otherwise = divZeroError
889 quotRem (W64# x#) y@(W64# y#)
890 | y /= 0 = (W64# (x# `quotWord#` y#), W64# (x# `remWord#` y#))
891 | otherwise = divZeroError
892 divMod (W64# x#) y@(W64# y#)
893 | y /= 0 = (W64# (x# `quotWord#` y#), W64# (x# `remWord#` y#))
894 | otherwise = divZeroError
895 toInteger (W64# x#)
896 | i# >=# 0# = smallInteger i#
897 | otherwise = wordToInteger x#
898 where
899 !i# = word2Int# x#
900
901 instance Bits Word64 where
902 {-# INLINE shift #-}
903
904 (W64# x#) .&. (W64# y#) = W64# (x# `and#` y#)
905 (W64# x#) .|. (W64# y#) = W64# (x# `or#` y#)
906 (W64# x#) `xor` (W64# y#) = W64# (x# `xor#` y#)
907 complement (W64# x#) = W64# (x# `xor#` mb#)
908 where !(W64# mb#) = maxBound
909 (W64# x#) `shift` (I# i#)
910 | i# >=# 0# = W64# (x# `shiftL#` i#)
911 | otherwise = W64# (x# `shiftRL#` negateInt# i#)
912 (W64# x#) `rotate` (I# i#)
913 | i'# ==# 0# = W64# x#
914 | otherwise = W64# ((x# `uncheckedShiftL#` i'#) `or#`
915 (x# `uncheckedShiftRL#` (64# -# i'#)))
916 where
917 !i'# = word2Int# (int2Word# i# `and#` int2Word# 63#)
918 bitSize _ = 64
919 isSigned _ = False
920
921 {-# RULES
922 "fromIntegral/a->Word64" fromIntegral = \x -> case fromIntegral x of W# x# -> W64# x#
923 "fromIntegral/Word64->a" fromIntegral = \(W64# x#) -> fromIntegral (W# x#)
924 #-}
925
926 uncheckedShiftL64# :: Word# -> Int# -> Word#
927 uncheckedShiftL64# = uncheckedShiftL#
928
929 uncheckedShiftRL64# :: Word# -> Int# -> Word#
930 uncheckedShiftRL64# = uncheckedShiftRL#
931
932 #endif
933
934 instance Show Word64 where
935 showsPrec p x = showsPrec p (toInteger x)
936
937 instance Real Word64 where
938 toRational x = toInteger x % 1
939
940 instance Bounded Word64 where
941 minBound = 0
942 maxBound = 0xFFFFFFFFFFFFFFFF
943
944 instance Ix Word64 where
945 range (m,n) = [m..n]
946 unsafeIndex (m,_) i = fromIntegral (i - m)
947 inRange (m,n) i = m <= i && i <= n
948
949 instance Read Word64 where
950 readsPrec p s = [(fromInteger x, r) | (x, r) <- readsPrec p s]