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