content: {-
  (c) The University of Glasgow, 2000-2006
  
  \section{Fast booleans}
  -}
  
  {-# LANGUAGE CPP, MagicHash #-}
  
  module Eta.Utils.FastBool (
      --fastBool could be called bBox; isFastTrue, bUnbox; but they're not
      FastBool, fastBool, isFastTrue, fastOr, fastAnd
    ) where
  
  -- Import the beggars
  import GHC.Exts
  #ifdef DEBUG
  import Eta.Utils.Panic
  #endif
  
  type FastBool = Int#
  fastBool True  = 1#
  fastBool False = 0#
  
  #ifdef DEBUG
  --then waste time deciding whether to panic. FastBool should normally
  --be at least as fast as Bool, one would hope...
  
  isFastTrue 1# = True
  isFastTrue 0# = False
  isFastTrue _ = panic "FastTypes: isFastTrue"
  
  -- note that fastOr and fastAnd are strict in both arguments
  -- since they are unboxed
  fastOr 1# _ = 1#
  fastOr 0# x = x
  fastOr _  _ = panicFastInt "FastTypes: fastOr"
  
  fastAnd 0# _ = 0#
  fastAnd 1# x = x
  fastAnd _  _ = panicFastInt "FastTypes: fastAnd"
  
  --these "panicFastInt"s (formerly known as "panic#") rely on
  --FastInt = FastBool ( = Int# presumably),
  --haha, true enough when __GLASGOW_HASKELL__.  Why can't we have functions
  --that return _|_ be kind-polymorphic ( ?? to be precise ) ?
  
  #else /* ! DEBUG */
  --Isn't comparison to zero sometimes faster on CPUs than comparison to 1?
  -- (since using Int# as _synonym_ fails to guarantee that it will
  --   only take on values of 0 and 1)
  isFastTrue 0# = False
  isFastTrue _ = True
  
  -- note that fastOr and fastAnd are strict in both arguments
  -- since they are unboxed
  -- Also, to avoid incomplete-pattern warning
  -- (and avoid wasting time with redundant runtime checks),
  -- we don't pattern-match on both 0# and 1# .
  fastOr 0# x = x
  fastOr _  _ = 1#
  
  fastAnd 0# _ = 0#
  fastAnd _  x = x
  
  #endif /* ! DEBUG */
  
  fastBool :: Bool -> FastBool
  isFastTrue :: FastBool -> Bool
  fastOr :: FastBool -> FastBool -> FastBool
  fastAnd :: FastBool -> FastBool -> FastBool
  