{-# language BangPatterns #-}
{-# language MagicHash #-}
{-# language UnboxedTuples #-}
{-# language ScopedTypeVariables #-}
module Data.Primitive.Unlifted.Atomic
( casUnliftedArray
) where
import Control.Monad.Primitive (PrimMonad,PrimState,primitive)
import Data.Primitive.Unlifted.Array (MutableUnliftedArray(..))
import Data.Primitive.Unlifted.Class (PrimUnlifted,Unlifted,toUnlifted#,fromUnlifted#)
import GHC.Exts (Any,MutableArrayArray#,MutableArray#,ArrayArray#,Int(I#))
import GHC.Exts (casArray#,isTrue#,(==#),unsafeCoerce#)
casUnliftedArray :: forall m a. (PrimMonad m, PrimUnlifted a)
=> MutableUnliftedArray (PrimState m) a
-> Int
-> a
-> a
-> m (Bool,a)
{-# INLINE casUnliftedArray #-}
casUnliftedArray (MutableUnliftedArray arr#) (I# i#) old new =
primitive $ \s0 ->
let !uold = (unsafeCoerce# :: Unlifted a -> Any) (toUnlifted# old)
!unew = (unsafeCoerce# :: Unlifted a -> Any) (toUnlifted# new)
in case casArray# ((unsafeCoerce# :: MutableArrayArray# (PrimState m) -> MutableArray# (PrimState m) Any) arr#) i# uold unew s0 of
(# s1, n, ur #) -> (# s1, (isTrue# (n ==# 0# ),fromUnlifted# ((unsafeCoerce# :: Any -> Unlifted a) ur)) #)