{-# LANGUAGE BangPatterns, MagicHash, CPP #-}
#ifdef SAFE
{-# LANGUAGE Safe #-}
#else
{-# LANGUAGE Unsafe #-}
#endif
module Data.RangeSet.Internal.Heuristics (stayedSame, ifStayedSame) where

import Prelude

#ifndef SAFE
import GHC.Exts (reallyUnsafePtrEquality#, isTrue#)
#endif

import Data.RangeSet.Internal.Types

#ifndef SAFE
{-# INLINE ptrEq #-}
ptrEq :: a -> a -> Bool
ptrEq :: a -> a -> Bool
ptrEq a
x a
y = Int# -> Bool
isTrue# (a -> a -> Int#
forall a. a -> a -> Int#
reallyUnsafePtrEquality# a
x a
y)
#endif

{-# INLINE stayedSame #-}
{-|
This should /only/ be used to compare a set that is modified
with its original value. The assumption is that a set as stayed
the same if its size hasn't changed.
-}
stayedSame :: RangeSet a -- ^ the original set
           -> RangeSet a -- ^ the same (?) set post modification
           -> Bool
stayedSame :: RangeSet a -> RangeSet a -> Bool
stayedSame RangeSet a
before RangeSet a
after =
#ifdef SAFE
    size before == size after
#else
    RangeSet a
before RangeSet a -> RangeSet a -> Bool
forall a. a -> a -> Bool
`ptrEq` RangeSet a
after
#endif

{-# INLINE ifStayedSame #-}
ifStayedSame :: RangeSet a -> RangeSet a -> RangeSet a -> (RangeSet a -> RangeSet a) -> RangeSet a
ifStayedSame :: RangeSet a
-> RangeSet a
-> RangeSet a
-> (RangeSet a -> RangeSet a)
-> RangeSet a
ifStayedSame !RangeSet a
x !RangeSet a
x' RangeSet a
y RangeSet a -> RangeSet a
f = if RangeSet a -> Int
forall a. RangeSet a -> Int
size RangeSet a
x Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== RangeSet a -> Int
forall a. RangeSet a -> Int
size RangeSet a
x' then RangeSet a
y else RangeSet a -> RangeSet a
f RangeSet a
x'