[project @ 2002-06-14 08:17:08 by simonpj]
[ghc-base.git] / Data / Bits.hs
index 9b68618..ca240d4 100644 (file)
@@ -1,21 +1,24 @@
 {-# OPTIONS -fno-implicit-prelude #-}
 -----------------------------------------------------------------------------
--- 
+-- |
 -- Module      :  Data.Bits
 -- Copyright   :  (c) The University of Glasgow 2001
--- License     :  BSD-style (see the file libraries/core/LICENSE)
+-- License     :  BSD-style (see the file libraries/base/LICENSE)
 -- 
 -- Maintainer  :  libraries@haskell.org
 -- Stability   :  experimental
 -- Portability :  portable
 --
--- $Id: Bits.hs,v 1.2 2001/07/03 11:37:49 simonmar Exp $
---
--- Bitwise operations.
+--  This module defines bitwise operations for signed and unsigned
+--  integers.  Instances of the class 'Bits' for the 'Int' and
+--  'Integer' types are available from this module, and instances for
+--  explicitly sized integral types are available from the
+--  "Int" and "Word" modules.
 --
 -----------------------------------------------------------------------------
 
 module Data.Bits ( 
+  -- * The 'Bits' class
   Bits(
     (.&.), (.|.), xor, -- :: a -> a -> a
     complement,        -- :: a -> a
@@ -29,8 +32,13 @@ module Data.Bits (
     bitSize,           -- :: a -> Int
     isSigned           -- :: a -> Bool
   ),
+
+  -- * Shifts and rotates
+
+  -- $shifts
   shiftL, shiftR,      -- :: Bits a => a -> Int -> a
   rotateL, rotateR,    -- :: Bits a => a -> Int -> a
+
   -- instance Bits Int
   -- instance Bits Integer
  ) where
@@ -50,23 +58,64 @@ import GHC.Base
 --     Removing all fixities is a fairly safe fix; fixing the "one fixity
 --     per symbol per program" limitation in Hugs would take a lot longer.
 #ifndef __HUGS__
-infixl 8 `shift`, `rotate`
+infixl 8 `shift`, `rotate`, `shiftL`, `shiftR`, `rotateL`, `rotateR`
 infixl 7 .&.
 infixl 6 `xor`
 infixl 5 .|.
 #endif
 
+{-| 
+The 'Bits' class defines bitwise operations over integral types.
+
+* Bits are numbered from 0 with bit 0 being the least
+  significant bit.
+-}
 class Num a => Bits a where
-    (.&.), (.|.), xor :: a -> a -> a
+    -- | Bitwise \"and\"
+    (.&.) :: a -> a -> a
+
+    -- | Bitwise \"or\"
+    (.|.) :: a -> a -> a
+
+    -- | Bitwise \"xor\"
+    xor :: a -> a -> a
+
+    {-| Reverse all the bits in the argument -}
     complement        :: a -> a
+
+    {-| Signed shift the argument left by the specified number of bits.
+       Right shifts are specified by giving a negative value. -}
     shift             :: a -> Int -> a
+
+    {-| Signed rotate the argument left by the specified number of bits.
+       Right rotates are specified by giving a negative value.
+
+        'rotate' is well defined only if 'bitSize' is also well defined
+        ('bitSize' is undefined for 'Integer', for example).
+    -}
     rotate            :: a -> Int -> a
+
+    -- | @bit i@ is a value with the @i@th bit set
     bit               :: Int -> a
+
+    -- | @x \`setBit\` i@ is the same as @x .|. bit i@
     setBit            :: a -> Int -> a
+
+    -- | @x \`clearBit\` i@ is the same as @x .&. complement (bit i)@
     clearBit          :: a -> Int -> a
+
+    -- | @x \`complementBit\` i@ is the same as @x \`xor\` bit i@
     complementBit     :: a -> Int -> a
+
+    -- | Return 'True' if the @n@th bit of the argument is 1
     testBit           :: a -> Int -> Bool
+
+    {-| Return the number of bits in the type of the argument.  The actual
+        value of the argument is ignored -}
     bitSize           :: a -> Int
+
+    {-| Return 'True' if the argument is a signed type.  The actual
+        value of the argument is ignored -}
     isSigned          :: a -> Bool
 
     bit i               = 1 `shift` i
@@ -75,6 +124,10 @@ class Num a => Bits a where
     x `complementBit` i = x `xor` bit i
     x `testBit` i       = (x .&. bit i) /= 0
 
+-- $shifts
+-- These functions might sometimes be more convenient than the unified
+-- versions 'shift' and 'rotate'.
+
 shiftL, shiftR   :: Bits a => a -> Int -> a
 rotateL, rotateR :: Bits a => a -> Int -> a
 x `shiftL`  i = x `shift`  i
@@ -92,20 +145,13 @@ instance Bits Int where
         | i# >=# 0#            = I# (x# `iShiftL#` i#)
         | otherwise            = I# (x# `iShiftRA#` negateInt# i#)
     (I# x#) `rotate` (I# i#) =
-#if WORD_SIZE_IN_BYTES == 4
-        I# (word2Int# ((x'# `shiftL#` i'#) `or#`
-                       (x'# `shiftRL#` (32# -# i'#))))
-        where
-        x'# = int2Word# x#
-        i'# = word2Int# (int2Word# i# `and#` int2Word# 31#)
-#else
         I# (word2Int# ((x'# `shiftL#` i'#) `or#`
-                       (x'# `shiftRL#` (64# -# i'#))))
+                       (x'# `shiftRL#` (wsib -# i'#))))
         where
         x'# = int2Word# x#
-        i'# = word2Int# (int2Word# i# `and#` int2Word# 63#)
-#endif
-    bitSize  _                 = WORD_SIZE_IN_BYTES * 8
+        i'# = word2Int# (int2Word# i# `and#` int2Word# (wsib -# 1#))
+       wsib = WORD_SIZE_IN_BITS#   {- work around preprocessor problem (??) -}
+    bitSize  _                 = WORD_SIZE_IN_BITS
     isSigned _                 = True
 
 instance Bits Integer where