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