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

{-# OPTIONS_HADDOCK hide #-}

-- | Really unsafe pointer equality
module Data.Strict.ContainersUtils.Autogen.PtrEquality (ptrEq, hetPtrEq) where

#ifdef __GLASGOW_HASKELL__
import GHC.Exts ( reallyUnsafePtrEquality# )
import Unsafe.Coerce ( unsafeCoerce )
import GHC.Exts ( Int#, isTrue# )
#endif

-- | Checks if two pointers are equal. Yes means yes;
-- no means maybe. The values should be forced to at least
-- WHNF before comparison to get moderately reliable results.
ptrEq :: a -> a -> Bool

-- | Checks if two pointers are equal, without requiring
-- them to have the same type. The values should be forced
-- to at least WHNF before comparison to get moderately
-- reliable results.
hetPtrEq :: a -> b -> Bool

#ifdef __GLASGOW_HASKELL__
ptrEq :: forall a. a -> a -> Bool
ptrEq a
x a
y = Int# -> Bool
isTrue# (a -> a -> Int#
forall a b. a -> b -> Int#
reallyUnsafePtrEquality# a
x a
y)
hetPtrEq :: forall a b. a -> b -> Bool
hetPtrEq a
x b
y = Int# -> Bool
isTrue# ((Any -> Any -> Int#) -> a -> b -> Int#
forall a b. a -> b
unsafeCoerce (x -> x -> Int#
forall {x}. x -> x -> Int#
forall a b. a -> b -> Int#
reallyUnsafePtrEquality# :: x -> x -> Int#) a
x b
y)

#else
-- Not GHC
ptrEq _ _ = False
hetPtrEq _ _ = False
#endif

{-# INLINE ptrEq #-}
{-# INLINE hetPtrEq #-}

infix 4 `ptrEq`
infix 4 `hetPtrEq`