    {-# LANGUAGE CPP #-}
    #ifdef __GLASGOW_HASKELL__
    {-# LANGUAGE MagicHash #-}
    {-# LANGUAGE Trustworthy #-}
    #endif

    #include "containers.h"

    -----------------------------------------------------------------------------
    -- |
    -- Module      :  Utils.Containers.Internal.BitUtil
    -- Copyright   :  (c) Clark Gaebel 2012
    --                (c) Johan Tibel 2012
    -- License     :  BSD-style
    -- Maintainer  :  libraries@haskell.org
    -- Portability :  portable
    -----------------------------------------------------------------------------
    --
    -- = WARNING
    --
    -- This module is considered __internal__.
    --
    -- The Package Versioning Policy __does not apply__.
    --
    -- The contents of this module may change __in any way whatsoever__
    -- and __without any warning__ between minor versions of this package.
    --
    -- Authors importing this module are expected to track development
    -- closely.

    module Utils.Containers.Internal.BitUtil
        ( shiftLL
        , shiftRL
        , wordSize
        , iShiftRL
        ) where

    import Data.Bits (unsafeShiftL, unsafeShiftR, finiteBitSize)
    #ifdef __GLASGOW_HASKELL__
    import GHC.Exts (Int(..), uncheckedIShiftRL#)
    #endif

    -- Right and left logical shifts.
    --
    -- Precondition for defined behavior: 0 <= shift amount < wordSize
    shiftRL, shiftLL :: Word -> Int -> Word
    shiftRL :: Word -> Int -> Word
    shiftRL = Word -> Int -> Word
    forall a. Bits a => a -> Int -> a
    unsafeShiftR
    shiftLL :: Word -> Int -> Word
    shiftLL = Word -> Int -> Word
    forall a. Bits a => a -> Int -> a
    unsafeShiftL

    {-# INLINE wordSize #-}
    wordSize :: Int
    wordSize :: Int
    wordSize = Word -> Int
    forall b. FiniteBits b => b -> Int
    finiteBitSize (Word
    0 :: Word)

    -- Right logical shift.
    --
    -- Precondition for defined behavior: 0 <= shift amount < wordSize
    iShiftRL :: Int -> Int -> Int
    #ifdef __GLASGOW_HASKELL__
    iShiftRL :: Int -> Int -> Int
    iShiftRL (I# Int#
    x#) (I# Int#
    sh#) = Int# -> Int
    I# (Int# -> Int# -> Int#
    uncheckedIShiftRL# Int#
    x# Int#
    sh#)
    #else
    iShiftRL x sh = fromIntegral (unsafeShiftR (fromIntegral x :: Word) sh)
    #endif