go-ify foldr2
[packages/base.git] / 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 uncheckedShiftL64#,
25 uncheckedShiftRL64#,
26 byteSwap16,
27 byteSwap32,
28 byteSwap64
29 ) where
30
31 import Data.Bits
32 import Data.Maybe
33
34 #if WORD_SIZE_IN_BITS < 64
35 import GHC.IntWord64
36 #endif
37
38 -- import {-# SOURCE #-} GHC.Exception
39 import GHC.Base
40 import GHC.Enum
41 import GHC.Num
42 import GHC.Real
43 import GHC.Read
44 import GHC.Arr
45 import GHC.Show
46 import GHC.Float () -- for RealFrac methods
47
48 ------------------------------------------------------------------------
49 -- type Word8
50 ------------------------------------------------------------------------
51
52 -- Word8 is represented in the same way as Word. Operations may assume
53 -- and must ensure that it holds only values from its logical range.
54
55 data {-# CTYPE "HsWord8" #-} Word8 = W8# Word# deriving (Eq, Ord)
56 -- ^ 8-bit unsigned integer type
57
58 instance Show Word8 where
59 showsPrec p x = showsPrec p (fromIntegral x :: Int)
60
61 instance Num Word8 where
62 (W8# x#) + (W8# y#) = W8# (narrow8Word# (x# `plusWord#` y#))
63 (W8# x#) - (W8# y#) = W8# (narrow8Word# (x# `minusWord#` y#))
64 (W8# x#) * (W8# y#) = W8# (narrow8Word# (x# `timesWord#` y#))
65 negate (W8# x#) = W8# (narrow8Word# (int2Word# (negateInt# (word2Int# x#))))
66 abs x = x
67 signum 0 = 0
68 signum _ = 1
69 fromInteger i = W8# (narrow8Word# (integerToWord i))
70
71 instance Real Word8 where
72 toRational x = toInteger x % 1
73
74 instance Enum Word8 where
75 succ x
76 | x /= maxBound = x + 1
77 | otherwise = succError "Word8"
78 pred x
79 | x /= minBound = x - 1
80 | otherwise = predError "Word8"
81 toEnum i@(I# i#)
82 | i >= 0 && i <= fromIntegral (maxBound::Word8)
83 = W8# (int2Word# i#)
84 | otherwise = toEnumError "Word8" i (minBound::Word8, maxBound::Word8)
85 fromEnum (W8# x#) = I# (word2Int# x#)
86 enumFrom = boundedEnumFrom
87 enumFromThen = boundedEnumFromThen
88
89 instance Integral Word8 where
90 quot (W8# x#) y@(W8# y#)
91 | y /= 0 = W8# (x# `quotWord#` y#)
92 | otherwise = divZeroError
93 rem (W8# x#) y@(W8# y#)
94 | y /= 0 = W8# (x# `remWord#` y#)
95 | otherwise = divZeroError
96 div (W8# x#) y@(W8# y#)
97 | y /= 0 = W8# (x# `quotWord#` y#)
98 | otherwise = divZeroError
99 mod (W8# x#) y@(W8# y#)
100 | y /= 0 = W8# (x# `remWord#` y#)
101 | otherwise = divZeroError
102 quotRem (W8# x#) y@(W8# y#)
103 | y /= 0 = case x# `quotRemWord#` y# of
104 (# q, r #) ->
105 (W8# q, W8# r)
106 | otherwise = divZeroError
107 divMod (W8# x#) y@(W8# y#)
108 | y /= 0 = (W8# (x# `quotWord#` y#), W8# (x# `remWord#` y#))
109 | otherwise = divZeroError
110 toInteger (W8# x#) = smallInteger (word2Int# x#)
111
112 instance Bounded Word8 where
113 minBound = 0
114 maxBound = 0xFF
115
116 instance Ix Word8 where
117 range (m,n) = [m..n]
118 unsafeIndex (m,_) i = fromIntegral (i - m)
119 inRange (m,n) i = m <= i && i <= n
120
121 instance Read Word8 where
122 readsPrec p s = [(fromIntegral (x::Int), r) | (x, r) <- readsPrec p s]
123
124 instance Bits Word8 where
125 {-# INLINE shift #-}
126 {-# INLINE bit #-}
127 {-# INLINE testBit #-}
128
129 (W8# x#) .&. (W8# y#) = W8# (x# `and#` y#)
130 (W8# x#) .|. (W8# y#) = W8# (x# `or#` y#)
131 (W8# x#) `xor` (W8# y#) = W8# (x# `xor#` y#)
132 complement (W8# x#) = W8# (x# `xor#` mb#)
133 where !(W8# mb#) = maxBound
134 (W8# x#) `shift` (I# i#)
135 | isTrue# (i# >=# 0#) = W8# (narrow8Word# (x# `shiftL#` i#))
136 | otherwise = W8# (x# `shiftRL#` negateInt# i#)
137 (W8# x#) `shiftL` (I# i#) = W8# (narrow8Word# (x# `shiftL#` i#))
138 (W8# x#) `unsafeShiftL` (I# i#) =
139 W8# (narrow8Word# (x# `uncheckedShiftL#` i#))
140 (W8# x#) `shiftR` (I# i#) = W8# (x# `shiftRL#` i#)
141 (W8# x#) `unsafeShiftR` (I# i#) = W8# (x# `uncheckedShiftRL#` i#)
142 (W8# x#) `rotate` (I# i#)
143 | isTrue# (i'# ==# 0#) = W8# x#
144 | otherwise = W8# (narrow8Word# ((x# `uncheckedShiftL#` i'#) `or#`
145 (x# `uncheckedShiftRL#` (8# -# i'#))))
146 where
147 !i'# = word2Int# (int2Word# i# `and#` 7##)
148 bitSizeMaybe i = Just (finiteBitSize i)
149 bitSize i = finiteBitSize i
150 isSigned _ = False
151 popCount (W8# x#) = I# (word2Int# (popCnt8# x#))
152 bit = bitDefault
153 testBit = testBitDefault
154
155 instance FiniteBits Word8 where
156 finiteBitSize _ = 8
157
158 {-# RULES
159 "fromIntegral/Word8->Word8" fromIntegral = id :: Word8 -> Word8
160 "fromIntegral/Word8->Integer" fromIntegral = toInteger :: Word8 -> Integer
161 "fromIntegral/a->Word8" fromIntegral = \x -> case fromIntegral x of W# x# -> W8# (narrow8Word# x#)
162 "fromIntegral/Word8->a" fromIntegral = \(W8# x#) -> fromIntegral (W# x#)
163 #-}
164
165 {-# RULES
166 "properFraction/Float->(Word8,Float)"
167 properFraction = \x ->
168 case properFraction x of {
169 (n, y) -> ((fromIntegral :: Int -> Word8) n, y :: Float) }
170 "truncate/Float->Word8"
171 truncate = (fromIntegral :: Int -> Word8) . (truncate :: Float -> Int)
172 "floor/Float->Word8"
173 floor = (fromIntegral :: Int -> Word8) . (floor :: Float -> Int)
174 "ceiling/Float->Word8"
175 ceiling = (fromIntegral :: Int -> Word8) . (ceiling :: Float -> Int)
176 "round/Float->Word8"
177 round = (fromIntegral :: Int -> Word8) . (round :: Float -> Int)
178 #-}
179
180 {-# RULES
181 "properFraction/Double->(Word8,Double)"
182 properFraction = \x ->
183 case properFraction x of {
184 (n, y) -> ((fromIntegral :: Int -> Word8) n, y :: Double) }
185 "truncate/Double->Word8"
186 truncate = (fromIntegral :: Int -> Word8) . (truncate :: Double -> Int)
187 "floor/Double->Word8"
188 floor = (fromIntegral :: Int -> Word8) . (floor :: Double -> Int)
189 "ceiling/Double->Word8"
190 ceiling = (fromIntegral :: Int -> Word8) . (ceiling :: Double -> Int)
191 "round/Double->Word8"
192 round = (fromIntegral :: Int -> Word8) . (round :: Double -> Int)
193 #-}
194
195 ------------------------------------------------------------------------
196 -- type Word16
197 ------------------------------------------------------------------------
198
199 -- Word16 is represented in the same way as Word. Operations may assume
200 -- and must ensure that it holds only values from its logical range.
201
202 data {-# CTYPE "HsWord16" #-} Word16 = W16# Word# deriving (Eq, Ord)
203 -- ^ 16-bit unsigned integer type
204
205 instance Show Word16 where
206 showsPrec p x = showsPrec p (fromIntegral x :: Int)
207
208 instance Num Word16 where
209 (W16# x#) + (W16# y#) = W16# (narrow16Word# (x# `plusWord#` y#))
210 (W16# x#) - (W16# y#) = W16# (narrow16Word# (x# `minusWord#` y#))
211 (W16# x#) * (W16# y#) = W16# (narrow16Word# (x# `timesWord#` y#))
212 negate (W16# x#) = W16# (narrow16Word# (int2Word# (negateInt# (word2Int# x#))))
213 abs x = x
214 signum 0 = 0
215 signum _ = 1
216 fromInteger i = W16# (narrow16Word# (integerToWord i))
217
218 instance Real Word16 where
219 toRational x = toInteger x % 1
220
221 instance Enum Word16 where
222 succ x
223 | x /= maxBound = x + 1
224 | otherwise = succError "Word16"
225 pred x
226 | x /= minBound = x - 1
227 | otherwise = predError "Word16"
228 toEnum i@(I# i#)
229 | i >= 0 && i <= fromIntegral (maxBound::Word16)
230 = W16# (int2Word# i#)
231 | otherwise = toEnumError "Word16" i (minBound::Word16, maxBound::Word16)
232 fromEnum (W16# x#) = I# (word2Int# x#)
233 enumFrom = boundedEnumFrom
234 enumFromThen = boundedEnumFromThen
235
236 instance Integral Word16 where
237 quot (W16# x#) y@(W16# y#)
238 | y /= 0 = W16# (x# `quotWord#` y#)
239 | otherwise = divZeroError
240 rem (W16# x#) y@(W16# y#)
241 | y /= 0 = W16# (x# `remWord#` y#)
242 | otherwise = divZeroError
243 div (W16# x#) y@(W16# y#)
244 | y /= 0 = W16# (x# `quotWord#` y#)
245 | otherwise = divZeroError
246 mod (W16# x#) y@(W16# y#)
247 | y /= 0 = W16# (x# `remWord#` y#)
248 | otherwise = divZeroError
249 quotRem (W16# x#) y@(W16# y#)
250 | y /= 0 = case x# `quotRemWord#` y# of
251 (# q, r #) ->
252 (W16# q, W16# r)
253 | otherwise = divZeroError
254 divMod (W16# x#) y@(W16# y#)
255 | y /= 0 = (W16# (x# `quotWord#` y#), W16# (x# `remWord#` y#))
256 | otherwise = divZeroError
257 toInteger (W16# x#) = smallInteger (word2Int# x#)
258
259 instance Bounded Word16 where
260 minBound = 0
261 maxBound = 0xFFFF
262
263 instance Ix Word16 where
264 range (m,n) = [m..n]
265 unsafeIndex (m,_) i = fromIntegral (i - m)
266 inRange (m,n) i = m <= i && i <= n
267
268 instance Read Word16 where
269 readsPrec p s = [(fromIntegral (x::Int), r) | (x, r) <- readsPrec p s]
270
271 instance Bits Word16 where
272 {-# INLINE shift #-}
273 {-# INLINE bit #-}
274 {-# INLINE testBit #-}
275
276 (W16# x#) .&. (W16# y#) = W16# (x# `and#` y#)
277 (W16# x#) .|. (W16# y#) = W16# (x# `or#` y#)
278 (W16# x#) `xor` (W16# y#) = W16# (x# `xor#` y#)
279 complement (W16# x#) = W16# (x# `xor#` mb#)
280 where !(W16# mb#) = maxBound
281 (W16# x#) `shift` (I# i#)
282 | isTrue# (i# >=# 0#) = W16# (narrow16Word# (x# `shiftL#` i#))
283 | otherwise = W16# (x# `shiftRL#` negateInt# i#)
284 (W16# x#) `shiftL` (I# i#) = W16# (narrow16Word# (x# `shiftL#` i#))
285 (W16# x#) `unsafeShiftL` (I# i#) =
286 W16# (narrow16Word# (x# `uncheckedShiftL#` i#))
287 (W16# x#) `shiftR` (I# i#) = W16# (x# `shiftRL#` i#)
288 (W16# x#) `unsafeShiftR` (I# i#) = W16# (x# `uncheckedShiftRL#` i#)
289 (W16# x#) `rotate` (I# i#)
290 | isTrue# (i'# ==# 0#) = W16# x#
291 | otherwise = W16# (narrow16Word# ((x# `uncheckedShiftL#` i'#) `or#`
292 (x# `uncheckedShiftRL#` (16# -# i'#))))
293 where
294 !i'# = word2Int# (int2Word# i# `and#` 15##)
295 bitSizeMaybe i = Just (finiteBitSize i)
296 bitSize i = finiteBitSize i
297 isSigned _ = False
298 popCount (W16# x#) = I# (word2Int# (popCnt16# x#))
299 bit = bitDefault
300 testBit = testBitDefault
301
302 instance FiniteBits Word16 where
303 finiteBitSize _ = 16
304
305 -- | Swap bytes in 'Word16'.
306 --
307 -- /Since: 4.7.0.0/
308 byteSwap16 :: Word16 -> Word16
309 byteSwap16 (W16# w#) = W16# (narrow16Word# (byteSwap16# w#))
310
311 {-# RULES
312 "fromIntegral/Word8->Word16" fromIntegral = \(W8# x#) -> W16# x#
313 "fromIntegral/Word16->Word16" fromIntegral = id :: Word16 -> Word16
314 "fromIntegral/Word16->Integer" fromIntegral = toInteger :: Word16 -> Integer
315 "fromIntegral/a->Word16" fromIntegral = \x -> case fromIntegral x of W# x# -> W16# (narrow16Word# x#)
316 "fromIntegral/Word16->a" fromIntegral = \(W16# x#) -> fromIntegral (W# x#)
317 #-}
318
319 {-# RULES
320 "properFraction/Float->(Word16,Float)"
321 properFraction = \x ->
322 case properFraction x of {
323 (n, y) -> ((fromIntegral :: Int -> Word16) n, y :: Float) }
324 "truncate/Float->Word16"
325 truncate = (fromIntegral :: Int -> Word16) . (truncate :: Float -> Int)
326 "floor/Float->Word16"
327 floor = (fromIntegral :: Int -> Word16) . (floor :: Float -> Int)
328 "ceiling/Float->Word16"
329 ceiling = (fromIntegral :: Int -> Word16) . (ceiling :: Float -> Int)
330 "round/Float->Word16"
331 round = (fromIntegral :: Int -> Word16) . (round :: Float -> Int)
332 #-}
333
334 {-# RULES
335 "properFraction/Double->(Word16,Double)"
336 properFraction = \x ->
337 case properFraction x of {
338 (n, y) -> ((fromIntegral :: Int -> Word16) n, y :: Double) }
339 "truncate/Double->Word16"
340 truncate = (fromIntegral :: Int -> Word16) . (truncate :: Double -> Int)
341 "floor/Double->Word16"
342 floor = (fromIntegral :: Int -> Word16) . (floor :: Double -> Int)
343 "ceiling/Double->Word16"
344 ceiling = (fromIntegral :: Int -> Word16) . (ceiling :: Double -> Int)
345 "round/Double->Word16"
346 round = (fromIntegral :: Int -> Word16) . (round :: Double -> Int)
347 #-}
348
349 ------------------------------------------------------------------------
350 -- type Word32
351 ------------------------------------------------------------------------
352
353 -- Word32 is represented in the same way as Word.
354 #if WORD_SIZE_IN_BITS > 32
355 -- Operations may assume and must ensure that it holds only values
356 -- from its logical range.
357
358 -- We can use rewrite rules for the RealFrac methods
359
360 {-# RULES
361 "properFraction/Float->(Word32,Float)"
362 properFraction = \x ->
363 case properFraction x of {
364 (n, y) -> ((fromIntegral :: Int -> Word32) n, y :: Float) }
365 "truncate/Float->Word32"
366 truncate = (fromIntegral :: Int -> Word32) . (truncate :: Float -> Int)
367 "floor/Float->Word32"
368 floor = (fromIntegral :: Int -> Word32) . (floor :: Float -> Int)
369 "ceiling/Float->Word32"
370 ceiling = (fromIntegral :: Int -> Word32) . (ceiling :: Float -> Int)
371 "round/Float->Word32"
372 round = (fromIntegral :: Int -> Word32) . (round :: Float -> Int)
373 #-}
374
375 {-# RULES
376 "properFraction/Double->(Word32,Double)"
377 properFraction = \x ->
378 case properFraction x of {
379 (n, y) -> ((fromIntegral :: Int -> Word32) n, y :: Double) }
380 "truncate/Double->Word32"
381 truncate = (fromIntegral :: Int -> Word32) . (truncate :: Double -> Int)
382 "floor/Double->Word32"
383 floor = (fromIntegral :: Int -> Word32) . (floor :: Double -> Int)
384 "ceiling/Double->Word32"
385 ceiling = (fromIntegral :: Int -> Word32) . (ceiling :: Double -> Int)
386 "round/Double->Word32"
387 round = (fromIntegral :: Int -> Word32) . (round :: Double -> Int)
388 #-}
389
390 #endif
391
392 data {-# CTYPE "HsWord32" #-} Word32 = W32# Word# deriving (Eq, Ord)
393 -- ^ 32-bit unsigned integer type
394
395 instance Num Word32 where
396 (W32# x#) + (W32# y#) = W32# (narrow32Word# (x# `plusWord#` y#))
397 (W32# x#) - (W32# y#) = W32# (narrow32Word# (x# `minusWord#` y#))
398 (W32# x#) * (W32# y#) = W32# (narrow32Word# (x# `timesWord#` y#))
399 negate (W32# x#) = W32# (narrow32Word# (int2Word# (negateInt# (word2Int# x#))))
400 abs x = x
401 signum 0 = 0
402 signum _ = 1
403 fromInteger i = W32# (narrow32Word# (integerToWord i))
404
405 instance Enum Word32 where
406 succ x
407 | x /= maxBound = x + 1
408 | otherwise = succError "Word32"
409 pred x
410 | x /= minBound = x - 1
411 | otherwise = predError "Word32"
412 toEnum i@(I# i#)
413 | i >= 0
414 #if WORD_SIZE_IN_BITS > 32
415 && i <= fromIntegral (maxBound::Word32)
416 #endif
417 = W32# (int2Word# i#)
418 | otherwise = toEnumError "Word32" i (minBound::Word32, maxBound::Word32)
419 #if WORD_SIZE_IN_BITS == 32
420 fromEnum x@(W32# x#)
421 | x <= fromIntegral (maxBound::Int)
422 = I# (word2Int# x#)
423 | otherwise = fromEnumError "Word32" x
424 enumFrom = integralEnumFrom
425 enumFromThen = integralEnumFromThen
426 enumFromTo = integralEnumFromTo
427 enumFromThenTo = integralEnumFromThenTo
428 #else
429 fromEnum (W32# x#) = I# (word2Int# x#)
430 enumFrom = boundedEnumFrom
431 enumFromThen = boundedEnumFromThen
432 #endif
433
434 instance Integral Word32 where
435 quot (W32# x#) y@(W32# y#)
436 | y /= 0 = W32# (x# `quotWord#` y#)
437 | otherwise = divZeroError
438 rem (W32# x#) y@(W32# y#)
439 | y /= 0 = W32# (x# `remWord#` y#)
440 | otherwise = divZeroError
441 div (W32# x#) y@(W32# y#)
442 | y /= 0 = W32# (x# `quotWord#` y#)
443 | otherwise = divZeroError
444 mod (W32# x#) y@(W32# y#)
445 | y /= 0 = W32# (x# `remWord#` y#)
446 | otherwise = divZeroError
447 quotRem (W32# x#) y@(W32# y#)
448 | y /= 0 = case x# `quotRemWord#` y# of
449 (# q, r #) ->
450 (W32# q, W32# r)
451 | otherwise = divZeroError
452 divMod (W32# x#) y@(W32# y#)
453 | y /= 0 = (W32# (x# `quotWord#` y#), W32# (x# `remWord#` y#))
454 | otherwise = divZeroError
455 toInteger (W32# x#)
456 #if WORD_SIZE_IN_BITS == 32
457 | isTrue# (i# >=# 0#) = smallInteger i#
458 | otherwise = wordToInteger x#
459 where
460 !i# = word2Int# x#
461 #else
462 = smallInteger (word2Int# x#)
463 #endif
464
465 instance Bits Word32 where
466 {-# INLINE shift #-}
467 {-# INLINE bit #-}
468 {-# INLINE testBit #-}
469
470 (W32# x#) .&. (W32# y#) = W32# (x# `and#` y#)
471 (W32# x#) .|. (W32# y#) = W32# (x# `or#` y#)
472 (W32# x#) `xor` (W32# y#) = W32# (x# `xor#` y#)
473 complement (W32# x#) = W32# (x# `xor#` mb#)
474 where !(W32# mb#) = maxBound
475 (W32# x#) `shift` (I# i#)
476 | isTrue# (i# >=# 0#) = W32# (narrow32Word# (x# `shiftL#` i#))
477 | otherwise = W32# (x# `shiftRL#` negateInt# i#)
478 (W32# x#) `shiftL` (I# i#) = W32# (narrow32Word# (x# `shiftL#` i#))
479 (W32# x#) `unsafeShiftL` (I# i#) =
480 W32# (narrow32Word# (x# `uncheckedShiftL#` i#))
481 (W32# x#) `shiftR` (I# i#) = W32# (x# `shiftRL#` i#)
482 (W32# x#) `unsafeShiftR` (I# i#) = W32# (x# `uncheckedShiftRL#` i#)
483 (W32# x#) `rotate` (I# i#)
484 | isTrue# (i'# ==# 0#) = W32# x#
485 | otherwise = W32# (narrow32Word# ((x# `uncheckedShiftL#` i'#) `or#`
486 (x# `uncheckedShiftRL#` (32# -# i'#))))
487 where
488 !i'# = word2Int# (int2Word# i# `and#` 31##)
489 bitSizeMaybe i = Just (finiteBitSize i)
490 bitSize i = finiteBitSize i
491 isSigned _ = False
492 popCount (W32# x#) = I# (word2Int# (popCnt32# x#))
493 bit = bitDefault
494 testBit = testBitDefault
495
496 instance FiniteBits Word32 where
497 finiteBitSize _ = 32
498
499 {-# RULES
500 "fromIntegral/Word8->Word32" fromIntegral = \(W8# x#) -> W32# x#
501 "fromIntegral/Word16->Word32" fromIntegral = \(W16# x#) -> W32# x#
502 "fromIntegral/Word32->Word32" fromIntegral = id :: Word32 -> Word32
503 "fromIntegral/Word32->Integer" fromIntegral = toInteger :: Word32 -> Integer
504 "fromIntegral/a->Word32" fromIntegral = \x -> case fromIntegral x of W# x# -> W32# (narrow32Word# x#)
505 "fromIntegral/Word32->a" fromIntegral = \(W32# x#) -> fromIntegral (W# x#)
506 #-}
507
508 instance Show Word32 where
509 #if WORD_SIZE_IN_BITS < 33
510 showsPrec p x = showsPrec p (toInteger x)
511 #else
512 showsPrec p x = showsPrec p (fromIntegral x :: Int)
513 #endif
514
515
516 instance Real Word32 where
517 toRational x = toInteger x % 1
518
519 instance Bounded Word32 where
520 minBound = 0
521 maxBound = 0xFFFFFFFF
522
523 instance Ix Word32 where
524 range (m,n) = [m..n]
525 unsafeIndex (m,_) i = fromIntegral (i - m)
526 inRange (m,n) i = m <= i && i <= n
527
528 instance Read Word32 where
529 #if WORD_SIZE_IN_BITS < 33
530 readsPrec p s = [(fromInteger x, r) | (x, r) <- readsPrec p s]
531 #else
532 readsPrec p s = [(fromIntegral (x::Int), r) | (x, r) <- readsPrec p s]
533 #endif
534
535 -- | Reverse order of bytes in 'Word32'.
536 --
537 -- /Since: 4.7.0.0/
538 byteSwap32 :: Word32 -> Word32
539 byteSwap32 (W32# w#) = W32# (narrow32Word# (byteSwap32# w#))
540
541 ------------------------------------------------------------------------
542 -- type Word64
543 ------------------------------------------------------------------------
544
545 #if WORD_SIZE_IN_BITS < 64
546
547 data {-# CTYPE "HsWord64" #-} Word64 = W64# Word64#
548 -- ^ 64-bit unsigned integer type
549
550 instance Eq Word64 where
551 (W64# x#) == (W64# y#) = isTrue# (x# `eqWord64#` y#)
552 (W64# x#) /= (W64# y#) = isTrue# (x# `neWord64#` y#)
553
554 instance Ord Word64 where
555 (W64# x#) < (W64# y#) = isTrue# (x# `ltWord64#` y#)
556 (W64# x#) <= (W64# y#) = isTrue# (x# `leWord64#` y#)
557 (W64# x#) > (W64# y#) = isTrue# (x# `gtWord64#` y#)
558 (W64# x#) >= (W64# y#) = isTrue# (x# `geWord64#` y#)
559
560 instance Num Word64 where
561 (W64# x#) + (W64# y#) = W64# (int64ToWord64# (word64ToInt64# x# `plusInt64#` word64ToInt64# y#))
562 (W64# x#) - (W64# y#) = W64# (int64ToWord64# (word64ToInt64# x# `minusInt64#` word64ToInt64# y#))
563 (W64# x#) * (W64# y#) = W64# (int64ToWord64# (word64ToInt64# x# `timesInt64#` word64ToInt64# y#))
564 negate (W64# x#) = W64# (int64ToWord64# (negateInt64# (word64ToInt64# x#)))
565 abs x = x
566 signum 0 = 0
567 signum _ = 1
568 fromInteger i = W64# (integerToWord64 i)
569
570 instance Enum Word64 where
571 succ x
572 | x /= maxBound = x + 1
573 | otherwise = succError "Word64"
574 pred x
575 | x /= minBound = x - 1
576 | otherwise = predError "Word64"
577 toEnum i@(I# i#)
578 | i >= 0 = W64# (wordToWord64# (int2Word# i#))
579 | otherwise = toEnumError "Word64" i (minBound::Word64, maxBound::Word64)
580 fromEnum x@(W64# x#)
581 | x <= fromIntegral (maxBound::Int)
582 = I# (word2Int# (word64ToWord# x#))
583 | otherwise = fromEnumError "Word64" x
584 enumFrom = integralEnumFrom
585 enumFromThen = integralEnumFromThen
586 enumFromTo = integralEnumFromTo
587 enumFromThenTo = integralEnumFromThenTo
588
589 instance Integral Word64 where
590 quot (W64# x#) y@(W64# y#)
591 | y /= 0 = W64# (x# `quotWord64#` y#)
592 | otherwise = divZeroError
593 rem (W64# x#) y@(W64# y#)
594 | y /= 0 = W64# (x# `remWord64#` y#)
595 | otherwise = divZeroError
596 div (W64# x#) y@(W64# y#)
597 | y /= 0 = W64# (x# `quotWord64#` y#)
598 | otherwise = divZeroError
599 mod (W64# x#) y@(W64# y#)
600 | y /= 0 = W64# (x# `remWord64#` y#)
601 | otherwise = divZeroError
602 quotRem (W64# x#) y@(W64# y#)
603 | y /= 0 = (W64# (x# `quotWord64#` y#), W64# (x# `remWord64#` y#))
604 | otherwise = divZeroError
605 divMod (W64# x#) y@(W64# y#)
606 | y /= 0 = (W64# (x# `quotWord64#` y#), W64# (x# `remWord64#` y#))
607 | otherwise = divZeroError
608 toInteger (W64# x#) = word64ToInteger x#
609
610 instance Bits Word64 where
611 {-# INLINE shift #-}
612 {-# INLINE bit #-}
613 {-# INLINE testBit #-}
614
615 (W64# x#) .&. (W64# y#) = W64# (x# `and64#` y#)
616 (W64# x#) .|. (W64# y#) = W64# (x# `or64#` y#)
617 (W64# x#) `xor` (W64# y#) = W64# (x# `xor64#` y#)
618 complement (W64# x#) = W64# (not64# x#)
619 (W64# x#) `shift` (I# i#)
620 | isTrue# (i# >=# 0#) = W64# (x# `shiftL64#` i#)
621 | otherwise = W64# (x# `shiftRL64#` negateInt# i#)
622 (W64# x#) `shiftL` (I# i#) = W64# (x# `shiftL64#` i#)
623 (W64# x#) `unsafeShiftL` (I# i#) = W64# (x# `uncheckedShiftL64#` i#)
624 (W64# x#) `shiftR` (I# i#) = W64# (x# `shiftRL64#` i#)
625 (W64# x#) `unsafeShiftR` (I# i#) = W64# (x# `uncheckedShiftRL64#` i#)
626 (W64# x#) `rotate` (I# i#)
627 | isTrue# (i'# ==# 0#) = W64# x#
628 | otherwise = W64# ((x# `uncheckedShiftL64#` i'#) `or64#`
629 (x# `uncheckedShiftRL64#` (64# -# i'#)))
630 where
631 !i'# = word2Int# (int2Word# i# `and#` 63##)
632 bitSizeMaybe i = Just (finiteBitSize i)
633 bitSize i = finiteBitSize i
634 isSigned _ = False
635 popCount (W64# x#) = I# (word2Int# (popCnt64# x#))
636 bit = bitDefault
637 testBit = testBitDefault
638
639 -- give the 64-bit shift operations the same treatment as the 32-bit
640 -- ones (see GHC.Base), namely we wrap them in tests to catch the
641 -- cases when we're shifting more than 64 bits to avoid unspecified
642 -- behaviour in the C shift operations.
643
644 shiftL64#, shiftRL64# :: Word64# -> Int# -> Word64#
645
646 a `shiftL64#` b | isTrue# (b >=# 64#) = wordToWord64# 0##
647 | otherwise = a `uncheckedShiftL64#` b
648
649 a `shiftRL64#` b | isTrue# (b >=# 64#) = wordToWord64# 0##
650 | otherwise = a `uncheckedShiftRL64#` b
651
652 {-# RULES
653 "fromIntegral/Int->Word64" fromIntegral = \(I# x#) -> W64# (int64ToWord64# (intToInt64# x#))
654 "fromIntegral/Word->Word64" fromIntegral = \(W# x#) -> W64# (wordToWord64# x#)
655 "fromIntegral/Word64->Int" fromIntegral = \(W64# x#) -> I# (word2Int# (word64ToWord# x#))
656 "fromIntegral/Word64->Word" fromIntegral = \(W64# x#) -> W# (word64ToWord# x#)
657 "fromIntegral/Word64->Word64" fromIntegral = id :: Word64 -> Word64
658 #-}
659
660 #else
661
662 -- Word64 is represented in the same way as Word.
663 -- Operations may assume and must ensure that it holds only values
664 -- from its logical range.
665
666 data {-# CTYPE "HsWord64" #-} Word64 = W64# Word# deriving (Eq, Ord)
667 -- ^ 64-bit unsigned integer type
668
669 instance Num Word64 where
670 (W64# x#) + (W64# y#) = W64# (x# `plusWord#` y#)
671 (W64# x#) - (W64# y#) = W64# (x# `minusWord#` y#)
672 (W64# x#) * (W64# y#) = W64# (x# `timesWord#` y#)
673 negate (W64# x#) = W64# (int2Word# (negateInt# (word2Int# x#)))
674 abs x = x
675 signum 0 = 0
676 signum _ = 1
677 fromInteger i = W64# (integerToWord i)
678
679 instance Enum Word64 where
680 succ x
681 | x /= maxBound = x + 1
682 | otherwise = succError "Word64"
683 pred x
684 | x /= minBound = x - 1
685 | otherwise = predError "Word64"
686 toEnum i@(I# i#)
687 | i >= 0 = W64# (int2Word# i#)
688 | otherwise = toEnumError "Word64" i (minBound::Word64, maxBound::Word64)
689 fromEnum x@(W64# x#)
690 | x <= fromIntegral (maxBound::Int)
691 = I# (word2Int# x#)
692 | otherwise = fromEnumError "Word64" x
693 enumFrom = integralEnumFrom
694 enumFromThen = integralEnumFromThen
695 enumFromTo = integralEnumFromTo
696 enumFromThenTo = integralEnumFromThenTo
697
698 instance Integral Word64 where
699 quot (W64# x#) y@(W64# y#)
700 | y /= 0 = W64# (x# `quotWord#` y#)
701 | otherwise = divZeroError
702 rem (W64# x#) y@(W64# y#)
703 | y /= 0 = W64# (x# `remWord#` y#)
704 | otherwise = divZeroError
705 div (W64# x#) y@(W64# y#)
706 | y /= 0 = W64# (x# `quotWord#` y#)
707 | otherwise = divZeroError
708 mod (W64# x#) y@(W64# y#)
709 | y /= 0 = W64# (x# `remWord#` y#)
710 | otherwise = divZeroError
711 quotRem (W64# x#) y@(W64# y#)
712 | y /= 0 = case x# `quotRemWord#` y# of
713 (# q, r #) ->
714 (W64# q, W64# r)
715 | otherwise = divZeroError
716 divMod (W64# x#) y@(W64# y#)
717 | y /= 0 = (W64# (x# `quotWord#` y#), W64# (x# `remWord#` y#))
718 | otherwise = divZeroError
719 toInteger (W64# x#)
720 | isTrue# (i# >=# 0#) = smallInteger i#
721 | otherwise = wordToInteger x#
722 where
723 !i# = word2Int# x#
724
725 instance Bits Word64 where
726 {-# INLINE shift #-}
727 {-# INLINE bit #-}
728 {-# INLINE testBit #-}
729
730 (W64# x#) .&. (W64# y#) = W64# (x# `and#` y#)
731 (W64# x#) .|. (W64# y#) = W64# (x# `or#` y#)
732 (W64# x#) `xor` (W64# y#) = W64# (x# `xor#` y#)
733 complement (W64# x#) = W64# (x# `xor#` mb#)
734 where !(W64# mb#) = maxBound
735 (W64# x#) `shift` (I# i#)
736 | isTrue# (i# >=# 0#) = W64# (x# `shiftL#` i#)
737 | otherwise = W64# (x# `shiftRL#` negateInt# i#)
738 (W64# x#) `shiftL` (I# i#) = W64# (x# `shiftL#` i#)
739 (W64# x#) `unsafeShiftL` (I# i#) = W64# (x# `uncheckedShiftL#` i#)
740 (W64# x#) `shiftR` (I# i#) = W64# (x# `shiftRL#` i#)
741 (W64# x#) `unsafeShiftR` (I# i#) = W64# (x# `uncheckedShiftRL#` i#)
742 (W64# x#) `rotate` (I# i#)
743 | isTrue# (i'# ==# 0#) = W64# x#
744 | otherwise = W64# ((x# `uncheckedShiftL#` i'#) `or#`
745 (x# `uncheckedShiftRL#` (64# -# i'#)))
746 where
747 !i'# = word2Int# (int2Word# i# `and#` 63##)
748 bitSizeMaybe i = Just (finiteBitSize i)
749 bitSize i = finiteBitSize i
750 isSigned _ = False
751 popCount (W64# x#) = I# (word2Int# (popCnt64# x#))
752 bit = bitDefault
753 testBit = testBitDefault
754
755 {-# RULES
756 "fromIntegral/a->Word64" fromIntegral = \x -> case fromIntegral x of W# x# -> W64# x#
757 "fromIntegral/Word64->a" fromIntegral = \(W64# x#) -> fromIntegral (W# x#)
758 #-}
759
760 uncheckedShiftL64# :: Word# -> Int# -> Word#
761 uncheckedShiftL64# = uncheckedShiftL#
762
763 uncheckedShiftRL64# :: Word# -> Int# -> Word#
764 uncheckedShiftRL64# = uncheckedShiftRL#
765
766 #endif
767
768 instance FiniteBits Word64 where
769 finiteBitSize _ = 64
770
771 instance Show Word64 where
772 showsPrec p x = showsPrec p (toInteger x)
773
774 instance Real Word64 where
775 toRational x = toInteger x % 1
776
777 instance Bounded Word64 where
778 minBound = 0
779 maxBound = 0xFFFFFFFFFFFFFFFF
780
781 instance Ix Word64 where
782 range (m,n) = [m..n]
783 unsafeIndex (m,_) i = fromIntegral (i - m)
784 inRange (m,n) i = m <= i && i <= n
785
786 instance Read Word64 where
787 readsPrec p s = [(fromInteger x, r) | (x, r) <- readsPrec p s]
788
789 -- | Reverse order of bytes in 'Word64'.
790 --
791 -- /Since: 4.7.0.0/
792 #if WORD_SIZE_IN_BITS < 64
793 byteSwap64 :: Word64 -> Word64
794 byteSwap64 (W64# w#) = W64# (byteSwap64# w#)
795 #else
796 byteSwap64 :: Word64 -> Word64
797 byteSwap64 (W64# w#) = W64# (byteSwap# w#)
798 #endif