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