{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE MonoLocalBinds #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
module Test.Massiv.Array.Mutable
  ( -- * Spec for safe Mutable instance
    mutableSpec
  , prop_GenerateArray
  , prop_iMapiMapM
  , prop_Shrink
  , prop_GrowShrink
  , prop_unfoldrList
  , prop_unfoldrReverseUnfoldl
  , prop_toStreamArrayMutable
  -- * Atomic ops spec
  , atomicIntSpec
  ) where

import Data.Bits
import Data.Functor.Identity
import Data.List as L
import Data.Massiv.Array as A
import qualified Data.Massiv.Vector.Stream as S
import Data.Massiv.Array.Mutable.Atomic
import Data.Massiv.Array.Unsafe
import Test.Massiv.Core.Common
import Test.Massiv.Utils as T
import UnliftIO.Async


-- prop_MapMapM :: forall r ix(Show (Array r ix Word), Eq (Array r ix Word), Mutable r ix Word) =>
--                 Fun Word Word -> ArrTiny D ix Word -> Property
-- prop_MapMapM r _ f (ArrTiny arr) =
--   computeAs r (A.map (apply f) arr) === runIdentity (A.mapMR r (return . apply f) arr)

prop_iMapiMapM ::
     forall r ix e. (Show (Array r ix e), Eq (Array r ix e), Mutable r ix e)
  => Fun (ix, e) e
  -> Array D ix e
  -> Property
prop_iMapiMapM :: Fun (ix, e) e -> Array D ix e -> Property
prop_iMapiMapM Fun (ix, e) e
f Array D ix e
arr =
  (Array D ix e -> Array r ix e
forall r ix e r'.
(Mutable r ix e, Load r' ix e) =>
Array r' ix e -> Array r ix e
compute ((ix -> e -> e) -> Array D ix e -> Array D ix e
forall r ix e' e.
Source r ix e' =>
(ix -> e' -> e) -> Array r ix e' -> Array D ix e
A.imap (((ix, e) -> e) -> ix -> e -> e
forall a b c. ((a, b) -> c) -> a -> b -> c
curry (Fun (ix, e) e -> (ix, e) -> e
forall a b. Fun a b -> a -> b
apply Fun (ix, e) e
f)) Array D ix e
arr) :: Array r ix e) Array r ix e -> Array r ix e -> Property
forall a. (Eq a, Show a) => a -> a -> Property
===
  Identity (Array r ix e) -> Array r ix e
forall a. Identity a -> a
runIdentity ((ix -> e -> Identity e) -> Array D ix e -> Identity (Array r ix e)
forall r ix b r' a (m :: * -> *).
(Source r' ix a, Mutable r ix b, Monad m) =>
(ix -> a -> m b) -> Array r' ix a -> m (Array r ix b)
A.imapM (\ix
ix e
e -> e -> Identity e
forall (f :: * -> *) a. Applicative f => a -> f a
pure (e -> Identity e) -> e -> Identity e
forall a b. (a -> b) -> a -> b
$ Fun (ix, e) e -> (ix, e) -> e
forall a b. Fun a b -> a -> b
apply Fun (ix, e) e
f (ix
ix, e
e)) Array D ix e
arr)

prop_GenerateArray ::
     forall r ix e.
     ( Show (Array r ix e)
     , Eq (Array r ix e)
     , Mutable r ix e
     , Show e
     , Arbitrary e
     , Arbitrary ix
     , Function ix
     , CoArbitrary ix
     )
  => Property
prop_GenerateArray :: Property
prop_GenerateArray =
  (Comp -> Sz ix -> Fun ix e -> IO ()) -> Property
forall prop. Testable prop => prop -> Property
property ((Comp -> Sz ix -> Fun ix e -> IO ()) -> Property)
-> (Comp -> Sz ix -> Fun ix e -> IO ()) -> Property
forall a b. (a -> b) -> a -> b
$ \Comp
comp Sz ix
sz Fun ix e
f' -> do
    let arr :: Array r ix e
arr = Comp -> Sz ix -> (ix -> e) -> Array r ix e
forall r ix e.
Construct r ix e =>
Comp -> Sz ix -> (ix -> e) -> Array r ix e
makeArray Comp
comp Sz ix
sz ix -> e
f :: Array r ix e
        arrST :: Array r ix e
arrST = (forall s. ST s (Array r ix e)) -> Array r ix e
forall a. (forall s. ST s a) -> a
runST (Sz ix -> (ix -> ST s e) -> ST s (Array r ix e)
forall r ix e (m :: * -> *).
(Mutable r ix e, PrimMonad m) =>
Sz ix -> (ix -> m e) -> m (Array r ix e)
generateArrayS (Array r ix e -> Sz ix
forall r ix e. Load r ix e => Array r ix e -> Sz ix
size Array r ix e
arr) (e -> ST s e
forall (m :: * -> *) a. Monad m => a -> m a
return (e -> ST s e) -> (ix -> e) -> ix -> ST s e
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Array r ix e -> ix -> e
forall r ix e. Source r ix e => Array r ix e -> ix -> e
evaluate' Array r ix e
arr))
        f :: ix -> e
f = Fun ix e -> ix -> e
forall a b. Fun a b -> a -> b
apply Fun ix e
f'
    Array r ix e
arrST Array r ix e -> Array r ix e -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` Array r ix e
arr
    Array r ix e
arrIO <- Comp -> Sz ix -> (ix -> IO e) -> IO (Array r ix e)
forall r ix e (m :: * -> *).
(MonadUnliftIO m, PrimMonad m, Mutable r ix e) =>
Comp -> Sz ix -> (ix -> m e) -> m (Array r ix e)
generateArray (Array r ix e -> Comp
forall r ix e. Load r ix e => Array r ix e -> Comp
getComp Array r ix e
arr) (Array r ix e -> Sz ix
forall r ix e. Load r ix e => Array r ix e -> Sz ix
size Array r ix e
arr) (Array r ix e -> ix -> IO e
forall r ix e (m :: * -> *).
(Source r ix e, MonadThrow m) =>
Array r ix e -> ix -> m e
evaluateM Array r ix e
arr)
    Array r ix e
arrIO Array r ix e -> Array r ix e -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` Array r ix e
arr

prop_Shrink ::
     forall r ix e.
     ( Show (Array r ix e)
     , Mutable r ix e
     , Source r Ix1 e
     , Arbitrary ix
     , Arbitrary e
     , Eq e
     )
  => Property
prop_Shrink :: Property
prop_Shrink  =
  (ArrIx r ix e -> Property) -> Property
forall prop. Testable prop => prop -> Property
property ((ArrIx r ix e -> Property) -> Property)
-> (ArrIx r ix e -> Property) -> Property
forall a b. (a -> b) -> a -> b
$ \ (ArrIx Array r ix e
arr ix
ix) -> (forall s. ST s Property) -> Property
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s Property) -> Property)
-> (forall s. ST s Property) -> Property
forall a b. (a -> b) -> a -> b
$ do
    MArray s r ix e
marr :: MArray s r ix e <- Array r ix e -> ST s (MArray (PrimState (ST s)) r ix e)
forall r ix e (m :: * -> *).
(Mutable r ix e, PrimMonad m) =>
Array r ix e -> m (MArray (PrimState m) r ix e)
thawS Array r ix e
arr
    Array r ix e
sarr <- Comp -> MArray (PrimState (ST s)) r ix e -> ST s (Array r ix e)
forall r ix e (m :: * -> *).
(Mutable r ix e, PrimMonad m) =>
Comp -> MArray (PrimState m) r ix e -> m (Array r ix e)
unsafeFreeze (Array r ix e -> Comp
forall r ix e. Load r ix e => Array r ix e -> Comp
getComp Array r ix e
arr) (MArray s r ix e -> ST s (Array r ix e))
-> ST s (MArray s r ix e) -> ST s (Array r ix e)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< MArray (PrimState (ST s)) r ix e
-> Sz ix -> ST s (MArray (PrimState (ST s)) r ix e)
forall r ix e (m :: * -> *).
(Mutable r ix e, PrimMonad m) =>
MArray (PrimState m) r ix e
-> Sz ix -> m (MArray (PrimState m) r ix e)
unsafeLinearShrink MArray s r ix e
MArray (PrimState (ST s)) r ix e
marr (ix -> Sz ix
forall ix. Index ix => ix -> Sz ix
Sz ix
ix)
    Property -> ST s Property
forall (f :: * -> *) a. Applicative f => a -> f a
pure ((Property -> Bool -> Property)
-> Property -> Array D Ix1 Bool -> Property
forall r ix e a.
Source r ix e =>
(a -> e -> a) -> a -> Array r ix e -> a
A.foldlS Property -> Bool -> Property
forall prop1 prop2.
(Testable prop1, Testable prop2) =>
prop1 -> prop2 -> Property
(.&&.) (Bool -> Property
forall prop. Testable prop => prop -> Property
property Bool
True) (Array D Ix1 Bool -> Property) -> Array D Ix1 Bool -> Property
forall a b. (a -> b) -> a -> b
$ (e -> e -> Bool)
-> Array r Ix1 e -> Array r Ix1 e -> Array D Ix1 Bool
forall r1 ix e1 r2 e2 e.
(Source r1 ix e1, Source r2 ix e2) =>
(e1 -> e2 -> e) -> Array r1 ix e1 -> Array r2 ix e2 -> Array D ix e
A.zipWith e -> e -> Bool
forall a. Eq a => a -> a -> Bool
(==) (Array r ix e -> Array r Ix1 e
forall r ix e.
(Load r ix e, Resize r ix) =>
Array r ix e -> Array r Ix1 e
flatten Array r ix e
arr) (Array r ix e -> Array r Ix1 e
forall r ix e.
(Load r ix e, Resize r ix) =>
Array r ix e -> Array r Ix1 e
flatten Array r ix e
sarr))

-- TODO: Improve runtime speed!
prop_GrowShrink ::
     forall r ix e.
     ( Eq (Array r ix e)
     , Show (Array r ix e)
     , Load (R r) ix e
     , Mutable r ix e
     , Extract r ix e
     , Arbitrary ix
     , Arbitrary e
     , Show e
     )
  => Property
prop_GrowShrink :: Property
prop_GrowShrink =
  (ArrNE r ix e -> NonNegative Ix1 -> e -> Property) -> Property
forall prop. Testable prop => prop -> Property
property ((ArrNE r ix e -> NonNegative Ix1 -> e -> Property) -> Property)
-> (ArrNE r ix e -> NonNegative Ix1 -> e -> Property) -> Property
forall a b. (a -> b) -> a -> b
$ \ (ArrNE Array r ix e
arr) (NonNegative Ix1
delta) e
e -> (forall s. ST s Property) -> Property
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s Property) -> Property)
-> (forall s. ST s Property) -> Property
forall a b. (a -> b) -> a -> b
$ do
    let sz :: Sz ix
sz = Array r ix e -> Sz ix
forall r ix e. Load r ix e => Array r ix e -> Sz ix
size (Array r ix e
arr :: Array r ix e)
        k :: Ix1
k = ix -> Dim -> Ix1
forall ix. Index ix => ix -> Dim -> Ix1
getDim' (Sz ix -> ix
forall ix. Sz ix -> ix
unSz Sz ix
sz) (Sz ix -> Dim
forall ix (proxy :: * -> *). Index ix => proxy ix -> Dim
dimensions Sz ix
sz)
        -- increase the outer most dimension, just so the structure doesn't change
        newSz :: Sz ix
newSz = ix -> Sz ix
forall ix. Index ix => ix -> Sz ix
Sz (ix -> Sz ix) -> ix -> Sz ix
forall a b. (a -> b) -> a -> b
$ ix -> Dim -> Ix1 -> ix
forall ix. Index ix => ix -> Dim -> Ix1 -> ix
setDim' (Sz ix -> ix
forall ix. Sz ix -> ix
unSz Sz ix
sz) (Sz ix -> Dim
forall ix (proxy :: * -> *). Index ix => proxy ix -> Dim
dimensions Sz ix
sz) (Ix1
k Ix1 -> Ix1 -> Ix1
forall a. Num a => a -> a -> a
+ Ix1
delta)
    MArray s r ix e
marr <- Array r ix e -> ST s (MArray (PrimState (ST s)) r ix e)
forall r ix e (m :: * -> *).
(Mutable r ix e, PrimMonad m) =>
Array r ix e -> m (MArray (PrimState m) r ix e)
thawS Array r ix e
arr
    MArray s r ix e
grownMarr <- MArray (PrimState (ST s)) r ix e
-> Sz ix -> ST s (MArray (PrimState (ST s)) r ix e)
forall r ix e (m :: * -> *).
(Mutable r ix e, PrimMonad m) =>
MArray (PrimState m) r ix e
-> Sz ix -> m (MArray (PrimState m) r ix e)
unsafeLinearGrow MArray s r ix e
MArray (PrimState (ST s)) r ix e
marr Sz ix
newSz
    -- Make sure we can write into the newly allocated area
    Bool -> ST s () -> ST s ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Ix1
delta Ix1 -> Ix1 -> Bool
forall a. Ord a => a -> a -> Bool
> Ix1
0) (ST s () -> ST s ()) -> ST s () -> ST s ()
forall a b. (a -> b) -> a -> b
$ ST s Bool -> ST s ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (ST s Bool -> ST s ()) -> ST s Bool -> ST s ()
forall a b. (a -> b) -> a -> b
$ MArray (PrimState (ST s)) r ix e -> ix -> e -> ST s Bool
forall r ix e (m :: * -> *).
(Mutable r ix e, PrimMonad m) =>
MArray (PrimState m) r ix e -> ix -> e -> m Bool
write MArray s r ix e
MArray (PrimState (ST s)) r ix e
grownMarr ((Ix1 -> Ix1) -> ix -> ix
forall ix. Index ix => (Ix1 -> Ix1) -> ix -> ix
liftIndex Ix1 -> Ix1
forall a. Enum a => a -> a
pred (Sz ix -> ix
forall ix. Sz ix -> ix
unSz Sz ix
newSz)) e
e
    Array r ix e
garr <- Array (R r) ix e -> Array r ix e
forall r ix e r'.
(Mutable r ix e, Load r' ix e) =>
Array r' ix e -> Array r ix e
compute (Array (R r) ix e -> Array r ix e)
-> (Array r ix e -> Array (R r) ix e)
-> Array r ix e
-> Array r ix e
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ix -> Sz ix -> Array r ix e -> Array (R r) ix e
forall r ix e.
Extract r ix e =>
ix -> Sz ix -> Array r ix e -> Array (R r) ix e
extract' ix
forall ix. Index ix => ix
zeroIndex Sz ix
sz (Array r ix e -> Array r ix e)
-> ST s (Array r ix e) -> ST s (Array r ix e)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Comp -> MArray (PrimState (ST s)) r ix e -> ST s (Array r ix e)
forall r ix e (m :: * -> *).
(Mutable r ix e, PrimMonad m) =>
Comp -> MArray (PrimState m) r ix e -> m (Array r ix e)
unsafeFreeze (Array r ix e -> Comp
forall r ix e. Load r ix e => Array r ix e -> Comp
getComp Array r ix e
arr) MArray s r ix e
MArray (PrimState (ST s)) r ix e
grownMarr
    Array r ix e
sarr <- MArray s r ix e -> ST s (Array r ix e)
forall r ix e (m :: * -> *).
(Mutable r ix e, PrimMonad m) =>
MArray (PrimState m) r ix e -> m (Array r ix e)
freezeS (MArray s r ix e -> ST s (Array r ix e))
-> ST s (MArray s r ix e) -> ST s (Array r ix e)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< MArray (PrimState (ST s)) r ix e
-> Sz ix -> ST s (MArray (PrimState (ST s)) r ix e)
forall r ix e (m :: * -> *).
(Mutable r ix e, PrimMonad m) =>
MArray (PrimState m) r ix e
-> Sz ix -> m (MArray (PrimState m) r ix e)
unsafeLinearShrink MArray s r ix e
MArray (PrimState (ST s)) r ix e
grownMarr Sz ix
sz
    Property -> ST s Property
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Array r ix e
garr Array r ix e -> Array r ix e -> Property
forall a. (Eq a, Show a) => a -> a -> Property
=== Array r ix e
arr Property -> Property -> Property
forall prop1 prop2.
(Testable prop1, Testable prop2) =>
prop1 -> prop2 -> Property
.&&. Array r ix e
sarr Array r ix e -> Array r ix e -> Property
forall a. (Eq a, Show a) => a -> a -> Property
=== Array r ix e
arr)



prop_unfoldrList ::
     forall r ix e.
     ( Show (Array r Ix1 e)
     , Eq (Array r Ix1 e)
     , Arbitrary ix
     , Arbitrary e
     , Show e
     , Resize r ix
     , Mutable r ix e
     , Mutable r Ix1 e
     )
  => Property
prop_unfoldrList :: Property
prop_unfoldrList =
  (Comp -> Sz ix -> Fun Word (e, Word) -> Word -> Property)
-> Property
forall prop. Testable prop => prop -> Property
property ((Comp -> Sz ix -> Fun Word (e, Word) -> Word -> Property)
 -> Property)
-> (Comp -> Sz ix -> Fun Word (e, Word) -> Word -> Property)
-> Property
forall a b. (a -> b) -> a -> b
$ \Comp
comp Sz ix
sz Fun Word (e, Word)
f (Word
i :: Word) ->
    let xs :: Array r ix e
xs = (forall s. ST s (Array r ix e)) -> Array r ix e
forall a. (forall s. ST s a) -> a
runST (Sz ix -> (Word -> ST s (e, Word)) -> Word -> ST s (Array r ix e)
forall r ix e a (m :: * -> *).
(Mutable r ix e, PrimMonad m) =>
Sz ix -> (a -> m (e, a)) -> a -> m (Array r ix e)
unfoldrPrimM_ Sz ix
sz ((e, Word) -> ST s (e, Word)
forall (f :: * -> *) a. Applicative f => a -> f a
pure ((e, Word) -> ST s (e, Word))
-> (Word -> (e, Word)) -> Word -> ST s (e, Word)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Fun Word (e, Word) -> Word -> (e, Word)
forall a b. Fun a b -> a -> b
apply Fun Word (e, Word)
f) Word
i) :: Array r ix e
        ys :: Array r Ix1 e
ys = Comp -> [e] -> Array r Ix1 e
forall r e. Mutable r Ix1 e => Comp -> [e] -> Array r Ix1 e
A.fromList Comp
comp (Ix1 -> [e] -> [e]
forall a. Ix1 -> [a] -> [a]
L.take (Sz ix -> Ix1
forall ix. Index ix => Sz ix -> Ix1
totalElem Sz ix
sz) ((Word -> Maybe (e, Word)) -> Word -> [e]
forall b a. (b -> Maybe (a, b)) -> b -> [a]
L.unfoldr ((e, Word) -> Maybe (e, Word)
forall a. a -> Maybe a
Just ((e, Word) -> Maybe (e, Word))
-> (Word -> (e, Word)) -> Word -> Maybe (e, Word)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Fun Word (e, Word) -> Word -> (e, Word)
forall a b. Fun a b -> a -> b
apply Fun Word (e, Word)
f) Word
i))
     in Array r ix e -> Array r Ix1 e
forall r ix e.
(Load r ix e, Resize r ix) =>
Array r ix e -> Array r Ix1 e
flatten Array r ix e
xs Array r Ix1 e -> Array r Ix1 e -> Property
forall a. (Eq a, Show a) => a -> a -> Property
=== Array r Ix1 e
ys


prop_unfoldrReverseUnfoldl ::
     forall r ix e.
     ( Show (Array r ix e)
     , Eq (Array r ix e)
     , Arbitrary ix
     , Arbitrary e
     , Show e
     , Source r ix e
     , Mutable r ix e
     )
  => Property
prop_unfoldrReverseUnfoldl :: Property
prop_unfoldrReverseUnfoldl =
  (Sz ix -> Fun Word (e, Word) -> Word -> IO ()) -> Property
forall prop. Testable prop => prop -> Property
property ((Sz ix -> Fun Word (e, Word) -> Word -> IO ()) -> Property)
-> (Sz ix -> Fun Word (e, Word) -> Word -> IO ()) -> Property
forall a b. (a -> b) -> a -> b
$ \ Sz ix
sz Fun Word (e, Word)
f (Word
i :: Word) ->
    let swapTuple :: (b, a) -> (a, b)
swapTuple (b
x, a
y) = (a
y, b
x)
        rev :: Array r ix e -> Array r ix e
rev Array r ix e
a =
          Array D ix e -> Array r ix e
forall r ix e r'.
(Mutable r ix e, Load r' ix e) =>
Array r' ix e -> Array r ix e
compute @r (Sz ix -> (ix -> ix) -> Array r ix e -> Array D ix e
forall r' ix' e ix.
(Source r' ix' e, Index ix) =>
Sz ix -> (ix -> ix') -> Array r' ix' e -> Array D ix e
backpermute' Sz ix
sz ((Ix1 -> Ix1) -> ix -> ix
forall ix. Index ix => (Ix1 -> Ix1) -> ix -> ix
liftIndex Ix1 -> Ix1
forall a. Enum a => a -> a
pred (ix -> ix) -> (ix -> ix) -> ix -> ix
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Ix1 -> Ix1 -> Ix1) -> ix -> ix -> ix
forall ix. Index ix => (Ix1 -> Ix1 -> Ix1) -> ix -> ix -> ix
liftIndex2 (-) (Sz ix -> ix
forall ix. Sz ix -> ix
unSz Sz ix
sz)) Array r ix e
a)
     in do Array r ix e
a1 :: Array r ix e <- Sz ix -> (Word -> IO (e, Word)) -> Word -> IO (Array r ix e)
forall r ix e a (m :: * -> *).
(Mutable r ix e, PrimMonad m) =>
Sz ix -> (a -> m (e, a)) -> a -> m (Array r ix e)
unfoldrPrimM_ @r Sz ix
sz ((e, Word) -> IO (e, Word)
forall (f :: * -> *) a. Applicative f => a -> f a
pure ((e, Word) -> IO (e, Word))
-> (Word -> (e, Word)) -> Word -> IO (e, Word)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Fun Word (e, Word) -> Word -> (e, Word)
forall a b. Fun a b -> a -> b
apply Fun Word (e, Word)
f) Word
i
           Array r ix e
a2 <- Sz ix -> (Word -> IO (Word, e)) -> Word -> IO (Array r ix e)
forall r ix e a (m :: * -> *).
(Mutable r ix e, PrimMonad m) =>
Sz ix -> (a -> m (a, e)) -> a -> m (Array r ix e)
unfoldlPrimM_ @r Sz ix
sz ((Word, e) -> IO (Word, e)
forall (f :: * -> *) a. Applicative f => a -> f a
pure ((Word, e) -> IO (Word, e))
-> (Word -> (Word, e)) -> Word -> IO (Word, e)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (e, Word) -> (Word, e)
forall b a. (b, a) -> (a, b)
swapTuple ((e, Word) -> (Word, e))
-> (Word -> (e, Word)) -> Word -> (Word, e)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Fun Word (e, Word) -> Word -> (e, Word)
forall a b. Fun a b -> a -> b
apply Fun Word (e, Word)
f) Word
i
           Array r ix e -> Array r ix e
rev Array r ix e
a1 Array r ix e -> Array r ix e -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` Array r ix e
a2

prop_toStreamArrayMutable ::
     (Mutable r ix e, Show (Array r ix e), Eq (Array r ix e)) => Array r ix e -> Property
prop_toStreamArrayMutable :: Array r ix e -> Property
prop_toStreamArrayMutable Array r ix e
arr =
  Array r ix e
arr Array r ix e -> Array r ix e -> Property
forall a. (Eq a, Show a) => a -> a -> Property
=== Sz ix -> Stream Id e -> Array r ix e
forall r ix e.
Mutable r ix e =>
Sz ix -> Stream Id e -> Array r ix e
S.unstreamExact (Array r ix e -> Sz ix
forall r ix e. Load r ix e => Array r ix e -> Sz ix
size Array r ix e
arr) (Steps Id e -> Stream Id e
forall (m :: * -> *) e. Steps m e -> Stream m e
S.stepsStream (Array DS Ix1 e -> Steps Id e
forall e. Array DS Ix1 e -> Steps Id e
toSteps (Array r ix e -> Array DS Ix1 e
forall r ix e. Source r ix e => Array r ix e -> Array DS Ix1 e
toStreamArray Array r ix e
arr)))


mutableSpec ::
     forall r ix e.
     ( Show (Array D ix e)
     , Show (Array r ix e)
     , Show (Array r Ix1 e)
     , Eq (Array r Ix1 e)
     , Load (R r) ix e
     , Eq (Array r ix e)
     , Typeable e
     , Show e
     , Eq e
     , Mutable r ix e
     , Mutable r Ix1 e
     , Extract r ix e
     , CoArbitrary ix
     , Arbitrary e
     , CoArbitrary e
     , Arbitrary ix
     , Typeable ix
     , Function ix
     , Function e
     )
  => Spec
mutableSpec :: Spec
mutableSpec = do
  String -> Spec -> Spec
forall a. HasCallStack => String -> SpecWith a -> SpecWith a
describe (String
"Mutable (" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> String
forall r ix e.
(Typeable r, Typeable ix, Typeable e) =>
String -> String
showsArrayType @r @ix @e String
") (Safe)") (Spec -> Spec) -> Spec -> Spec
forall a b. (a -> b) -> a -> b
$ do
    String -> Property -> SpecWith (Arg Property)
forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"GenerateArray" (Property -> SpecWith (Arg Property))
-> Property -> SpecWith (Arg Property)
forall a b. (a -> b) -> a -> b
$ Property -> Property
forall prop. Testable prop => prop -> Property
property (Property -> Property) -> Property -> Property
forall a b. (a -> b) -> a -> b
$ (Show (Array r ix e), Eq (Array r ix e), Mutable r ix e, Show e,
 Arbitrary e, Arbitrary ix, Function ix, CoArbitrary ix) =>
Property
forall r ix e.
(Show (Array r ix e), Eq (Array r ix e), Mutable r ix e, Show e,
 Arbitrary e, Arbitrary ix, Function ix, CoArbitrary ix) =>
Property
prop_GenerateArray @r @ix @e
    String -> Property -> SpecWith (Arg Property)
forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"Shrink" (Property -> SpecWith (Arg Property))
-> Property -> SpecWith (Arg Property)
forall a b. (a -> b) -> a -> b
$ Property -> Property
forall prop. Testable prop => prop -> Property
property (Property -> Property) -> Property -> Property
forall a b. (a -> b) -> a -> b
$ (Show (Array r ix e), Mutable r ix e, Source r Ix1 e, Arbitrary ix,
 Arbitrary e, Eq e) =>
Property
forall r ix e.
(Show (Array r ix e), Mutable r ix e, Source r Ix1 e, Arbitrary ix,
 Arbitrary e, Eq e) =>
Property
prop_Shrink @r @ix @e
    String -> Property -> SpecWith (Arg Property)
forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"GrowShrink" (Property -> SpecWith (Arg Property))
-> Property -> SpecWith (Arg Property)
forall a b. (a -> b) -> a -> b
$ Property -> Property
forall prop. Testable prop => prop -> Property
property (Property -> Property) -> Property -> Property
forall a b. (a -> b) -> a -> b
$ (Eq (Array r ix e), Show (Array r ix e), Load (R r) ix e,
 Mutable r ix e, Extract r ix e, Arbitrary ix, Arbitrary e,
 Show e) =>
Property
forall r ix e.
(Eq (Array r ix e), Show (Array r ix e), Load (R r) ix e,
 Mutable r ix e, Extract r ix e, Arbitrary ix, Arbitrary e,
 Show e) =>
Property
prop_GrowShrink @r @ix @e
    String -> Property -> SpecWith (Arg Property)
forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"map == mapM" (Property -> SpecWith (Arg Property))
-> Property -> SpecWith (Arg Property)
forall a b. (a -> b) -> a -> b
$ (Fun (ix, e) e -> Array D ix e -> Property) -> Property
forall prop. Testable prop => prop -> Property
property ((Fun (ix, e) e -> Array D ix e -> Property) -> Property)
-> (Fun (ix, e) e -> Array D ix e -> Property) -> Property
forall a b. (a -> b) -> a -> b
$ (Show (Array r ix e), Eq (Array r ix e), Mutable r ix e) =>
Fun (ix, e) e -> Array D ix e -> Property
forall r ix e.
(Show (Array r ix e), Eq (Array r ix e), Mutable r ix e) =>
Fun (ix, e) e -> Array D ix e -> Property
prop_iMapiMapM @r @ix @e
  String -> Spec -> Spec
forall a. HasCallStack => String -> SpecWith a -> SpecWith a
describe String
"Unfolding" (Spec -> Spec) -> Spec -> Spec
forall a b. (a -> b) -> a -> b
$ do
    String -> Property -> SpecWith (Arg Property)
forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"unfoldrList" (Property -> SpecWith (Arg Property))
-> Property -> SpecWith (Arg Property)
forall a b. (a -> b) -> a -> b
$ (Show (Array r Ix1 e), Eq (Array r Ix1 e), Arbitrary ix,
 Arbitrary e, Show e, Resize r ix, Mutable r ix e,
 Mutable r Ix1 e) =>
Property
forall r ix e.
(Show (Array r Ix1 e), Eq (Array r Ix1 e), Arbitrary ix,
 Arbitrary e, Show e, Resize r ix, Mutable r ix e,
 Mutable r Ix1 e) =>
Property
prop_unfoldrList @r @ix @e
    String -> Property -> SpecWith (Arg Property)
forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"unfoldrReverseUnfoldl" (Property -> SpecWith (Arg Property))
-> Property -> SpecWith (Arg Property)
forall a b. (a -> b) -> a -> b
$ (Show (Array r ix e), Eq (Array r ix e), Arbitrary ix, Arbitrary e,
 Show e, Source r ix e, Mutable r ix e) =>
Property
forall r ix e.
(Show (Array r ix e), Eq (Array r ix e), Arbitrary ix, Arbitrary e,
 Show e, Source r ix e, Mutable r ix e) =>
Property
prop_unfoldrReverseUnfoldl @r @ix @e
  String -> Spec -> Spec
forall a. HasCallStack => String -> SpecWith a -> SpecWith a
describe String
"Stream" (Spec -> Spec) -> Spec -> Spec
forall a b. (a -> b) -> a -> b
$
    String -> Property -> SpecWith (Arg Property)
forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"toStreamArrayMutable" (Property -> SpecWith (Arg Property))
-> Property -> SpecWith (Arg Property)
forall a b. (a -> b) -> a -> b
$ (Array r ix e -> Property) -> Property
forall prop. Testable prop => prop -> Property
property ((Mutable r ix e, Show (Array r ix e), Eq (Array r ix e)) =>
Array r ix e -> Property
forall r ix e.
(Mutable r ix e, Show (Array r ix e), Eq (Array r ix e)) =>
Array r ix e -> Property
prop_toStreamArrayMutable @r @ix @e)

-- | Try to write many elements into the same array cell concurrently, while keeping the
-- previous element for each write. With atomic writes, not a single element should be lost.
prop_atomicModifyIntArrayMany ::
     forall ix. (Show (Array P ix Int), Arbitrary ix, Index ix)
  => Property
prop_atomicModifyIntArrayMany :: Property
prop_atomicModifyIntArrayMany =
  (ArrIx P ix Ix1 -> Array B Ix1 Ix1 -> IO ()) -> Property
forall prop. Testable prop => prop -> Property
property ((ArrIx P ix Ix1 -> Array B Ix1 Ix1 -> IO ()) -> Property)
-> (ArrIx P ix Ix1 -> Array B Ix1 Ix1 -> IO ()) -> Property
forall a b. (a -> b) -> a -> b
$ \(ArrIx Array P ix Ix1
arr ix
ix) (Array B Ix1 Ix1
ys :: Array B Ix1 Int)  -> do
    MArray RealWorld P ix Ix1
marr <- Array P ix Ix1 -> IO (MArray RealWorld P ix Ix1)
forall r ix e (m :: * -> *).
(Mutable r ix e, MonadIO m) =>
Array r ix e -> m (MArray RealWorld r ix e)
thaw Array P ix Ix1
arr
    MArray (PrimState IO) P ix Ix1
-> ix -> (Ix1 -> Ix1) -> IO (Maybe Ix1)
forall ix (m :: * -> *).
(Index ix, PrimMonad m) =>
MArray (PrimState m) P ix Ix1
-> ix -> (Ix1 -> Ix1) -> m (Maybe Ix1)
atomicModifyIntArray MArray RealWorld P ix Ix1
MArray (PrimState IO) P ix Ix1
marr ((Ix1 -> Ix1) -> ix -> ix
forall ix. Index ix => (Ix1 -> Ix1) -> ix -> ix
liftIndex (Ix1 -> Ix1 -> Ix1
forall a. Num a => a -> a -> a
subtract Ix1
1 (Ix1 -> Ix1) -> (Ix1 -> Ix1) -> Ix1 -> Ix1
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ix1 -> Ix1
forall a. Num a => a -> a
negate) ix
ix) Ix1 -> Ix1
forall a. Enum a => a -> a
succ IO (Maybe Ix1) -> Maybe Ix1 -> IO ()
forall a. (HasCallStack, Show a, Eq a) => IO a -> a -> IO ()
`shouldReturn` Maybe Ix1
forall a. Maybe a
Nothing
    Array B Ix1 (Maybe Ix1)
mys <- (Ix1 -> IO (Maybe Ix1))
-> Array B Ix1 Ix1 -> IO (Array B Ix1 (Maybe Ix1))
forall (m :: * -> *) (t :: * -> *) a b.
(MonadUnliftIO m, Traversable t) =>
(a -> m b) -> t a -> m (t b)
mapConcurrently (MArray (PrimState IO) P ix Ix1
-> ix -> (Ix1 -> Ix1) -> IO (Maybe Ix1)
forall ix (m :: * -> *).
(Index ix, PrimMonad m) =>
MArray (PrimState m) P ix Ix1
-> ix -> (Ix1 -> Ix1) -> m (Maybe Ix1)
atomicModifyIntArray MArray RealWorld P ix Ix1
MArray (PrimState IO) P ix Ix1
marr ix
ix ((Ix1 -> Ix1) -> IO (Maybe Ix1))
-> (Ix1 -> Ix1 -> Ix1) -> Ix1 -> IO (Maybe Ix1)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ix1 -> Ix1 -> Ix1
forall a b. a -> b -> a
const) Array B Ix1 Ix1
ys
    Ix1
x <- MArray (PrimState IO) P ix Ix1 -> ix -> IO Ix1
forall r ix e (m :: * -> *).
(Mutable r ix e, PrimMonad m, MonadThrow m) =>
MArray (PrimState m) r ix e -> ix -> m e
A.readM MArray RealWorld P ix Ix1
MArray (PrimState IO) P ix Ix1
marr (ix
ix :: ix)
    let xs :: [Ix1]
xs = Ix1
x Ix1 -> [Ix1] -> [Ix1]
forall a. a -> [a] -> [a]
: [Ix1] -> Maybe [Ix1] -> [Ix1]
forall a. a -> Maybe a -> a
fromMaybe (String -> [Ix1]
forall a. HasCallStack => String -> a
error String
"atomicModifyIntArray") ([Maybe Ix1] -> Maybe [Ix1]
forall (t :: * -> *) (f :: * -> *) a.
(Traversable t, Applicative f) =>
t (f a) -> f (t a)
Prelude.sequenceA (Array B Ix1 (Maybe Ix1) -> [Maybe Ix1]
forall r ix e. Source r ix e => Array r ix e -> [e]
toList Array B Ix1 (Maybe Ix1)
mys))
    Ix1
y <- Array P ix Ix1 -> ix -> IO Ix1
forall r ix e (m :: * -> *).
(Manifest r ix e, MonadThrow m) =>
Array r ix e -> ix -> m e
indexM Array P ix Ix1
arr ix
ix
    [Ix1] -> [Ix1]
forall a. Ord a => [a] -> [a]
L.sort (Ix1
y Ix1 -> [Ix1] -> [Ix1]
forall a. a -> [a] -> [a]
: Array B Ix1 Ix1 -> [Ix1]
forall r ix e. Source r ix e => Array r ix e -> [e]
toList Array B Ix1 Ix1
ys) [Ix1] -> [Ix1] -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` [Ix1] -> [Ix1]
forall a. Ord a => [a] -> [a]
L.sort [Ix1]
xs

prop_atomicReadIntArray ::
     forall ix. (Show (Array P ix Int), Arbitrary ix, Index ix)
  => Property
prop_atomicReadIntArray :: Property
prop_atomicReadIntArray =
  (Array P ix Ix1 -> ix -> IO ()) -> Property
forall prop. Testable prop => prop -> Property
property ((Array P ix Ix1 -> ix -> IO ()) -> Property)
-> (Array P ix Ix1 -> ix -> IO ()) -> Property
forall a b. (a -> b) -> a -> b
$ \Array P ix Ix1
arr (ix
ix :: ix) -> do
    MArray RealWorld P ix Ix1
marr <- Array P ix Ix1 -> IO (MArray (PrimState IO) P ix Ix1)
forall r ix e (m :: * -> *).
(Mutable r ix e, PrimMonad m) =>
Array r ix e -> m (MArray (PrimState m) r ix e)
unsafeThaw Array P ix Ix1
arr
    Maybe Ix1
mx <- MArray (PrimState IO) P ix Ix1 -> ix -> IO (Maybe Ix1)
forall r ix e (m :: * -> *).
(Mutable r ix e, PrimMonad m) =>
MArray (PrimState m) r ix e -> ix -> m (Maybe e)
A.read MArray RealWorld P ix Ix1
MArray (PrimState IO) P ix Ix1
marr ix
ix
    MArray (PrimState IO) P ix Ix1 -> ix -> IO (Maybe Ix1)
forall ix (m :: * -> *).
(Index ix, PrimMonad m) =>
MArray (PrimState m) P ix Ix1 -> ix -> m (Maybe Ix1)
atomicReadIntArray MArray RealWorld P ix Ix1
MArray (PrimState IO) P ix Ix1
marr ix
ix IO (Maybe Ix1) -> Maybe Ix1 -> IO ()
forall a. (HasCallStack, Show a, Eq a) => IO a -> a -> IO ()
`shouldReturn` Maybe Ix1
mx

prop_atomicWriteIntArray ::
     forall ix. (Show (Array P ix Int), Arbitrary ix, Index ix)
  => Property
prop_atomicWriteIntArray :: Property
prop_atomicWriteIntArray =
  (Array P ix Ix1 -> ix -> Ix1 -> IO ()) -> Property
forall prop. Testable prop => prop -> Property
property ((Array P ix Ix1 -> ix -> Ix1 -> IO ()) -> Property)
-> (Array P ix Ix1 -> ix -> Ix1 -> IO ()) -> Property
forall a b. (a -> b) -> a -> b
$ \Array P ix Ix1
arr (ix
ix :: ix) (Ix1
e :: Int) -> do
    MArray RealWorld P ix Ix1
marr <- Array P ix Ix1 -> IO (MArray (PrimState IO) P ix Ix1)
forall r ix e (m :: * -> *).
(Mutable r ix e, PrimMonad m) =>
Array r ix e -> m (MArray (PrimState m) r ix e)
unsafeThaw Array P ix Ix1
arr
    Maybe Ix1
mx <- MArray (PrimState IO) P ix Ix1 -> ix -> IO (Maybe Ix1)
forall r ix e (m :: * -> *).
(Mutable r ix e, PrimMonad m) =>
MArray (PrimState m) r ix e -> ix -> m (Maybe e)
A.read MArray RealWorld P ix Ix1
MArray (PrimState IO) P ix Ix1
marr ix
ix
    MArray (PrimState IO) P ix Ix1 -> ix -> Ix1 -> IO Bool
forall ix (m :: * -> *).
(Index ix, PrimMonad m) =>
MArray (PrimState m) P ix Ix1 -> ix -> Ix1 -> m Bool
atomicWriteIntArray MArray RealWorld P ix Ix1
MArray (PrimState IO) P ix Ix1
marr ix
ix Ix1
e IO Bool -> Bool -> IO ()
forall a. (HasCallStack, Show a, Eq a) => IO a -> a -> IO ()
`shouldReturn` Maybe Ix1 -> Bool
forall a. Maybe a -> Bool
isJust Maybe Ix1
mx
    Maybe Ix1 -> (Ix1 -> IO ()) -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
T.forM_ Maybe Ix1
mx ((Ix1 -> IO ()) -> IO ()) -> (Ix1 -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \ Ix1
_ ->
      MArray (PrimState IO) P ix Ix1 -> ix -> IO (Maybe Ix1)
forall r ix e (m :: * -> *).
(Mutable r ix e, PrimMonad m) =>
MArray (PrimState m) r ix e -> ix -> m (Maybe e)
A.read MArray RealWorld P ix Ix1
MArray (PrimState IO) P ix Ix1
marr ix
ix IO (Maybe Ix1) -> Maybe Ix1 -> IO ()
forall a. (HasCallStack, Show a, Eq a) => IO a -> a -> IO ()
`shouldReturn` Ix1 -> Maybe Ix1
forall a. a -> Maybe a
Just Ix1
e

prop_atomicOpIntArray ::
     forall ix. (Show (Array P ix Int), Arbitrary ix, Index ix)
  => (Int -> Int -> Int)
  -> (forall m. PrimMonad m =>
                  MArray (PrimState m) P ix Int -> ix -> Int -> m (Maybe Int))
  -> Property
prop_atomicOpIntArray :: (Ix1 -> Ix1 -> Ix1)
-> (forall (m :: * -> *).
    PrimMonad m =>
    MArray (PrimState m) P ix Ix1 -> ix -> Ix1 -> m (Maybe Ix1))
-> Property
prop_atomicOpIntArray Ix1 -> Ix1 -> Ix1
f forall (m :: * -> *).
PrimMonad m =>
MArray (PrimState m) P ix Ix1 -> ix -> Ix1 -> m (Maybe Ix1)
atomicAction =
  (Array P ix Ix1 -> ix -> Ix1 -> IO ()) -> Property
forall prop. Testable prop => prop -> Property
property ((Array P ix Ix1 -> ix -> Ix1 -> IO ()) -> Property)
-> (Array P ix Ix1 -> ix -> Ix1 -> IO ()) -> Property
forall a b. (a -> b) -> a -> b
$ \Array P ix Ix1
arr (ix
ix :: ix) (Ix1
e :: Int) -> do
    MArray RealWorld P ix Ix1
marr <- Array P ix Ix1 -> IO (MArray (PrimState IO) P ix Ix1)
forall r ix e (m :: * -> *).
(Mutable r ix e, PrimMonad m) =>
Array r ix e -> m (MArray (PrimState m) r ix e)
unsafeThaw Array P ix Ix1
arr
    Maybe Ix1
mx <- MArray (PrimState IO) P ix Ix1 -> ix -> IO (Maybe Ix1)
forall r ix e (m :: * -> *).
(Mutable r ix e, PrimMonad m) =>
MArray (PrimState m) r ix e -> ix -> m (Maybe e)
A.read MArray RealWorld P ix Ix1
MArray (PrimState IO) P ix Ix1
marr ix
ix
    MArray (PrimState IO) P ix Ix1 -> ix -> Ix1 -> IO (Maybe Ix1)
forall (m :: * -> *).
PrimMonad m =>
MArray (PrimState m) P ix Ix1 -> ix -> Ix1 -> m (Maybe Ix1)
atomicAction MArray RealWorld P ix Ix1
MArray (PrimState IO) P ix Ix1
marr ix
ix Ix1
e IO (Maybe Ix1) -> Maybe Ix1 -> IO ()
forall a. (HasCallStack, Show a, Eq a) => IO a -> a -> IO ()
`shouldReturn` Maybe Ix1
mx
    Maybe Ix1 -> (Ix1 -> IO ()) -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
T.forM_ Maybe Ix1
mx ((Ix1 -> IO ()) -> IO ()) -> (Ix1 -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Ix1
x -> MArray (PrimState IO) P ix Ix1 -> ix -> IO Ix1
forall r ix e (m :: * -> *).
(Mutable r ix e, PrimMonad m, MonadThrow m) =>
MArray (PrimState m) r ix e -> ix -> m e
A.readM MArray RealWorld P ix Ix1
MArray (PrimState IO) P ix Ix1
marr ix
ix IO Ix1 -> Ix1 -> IO ()
forall a. (HasCallStack, Show a, Eq a) => IO a -> a -> IO ()
`shouldReturn` Ix1 -> Ix1 -> Ix1
f Ix1
x Ix1
e

prop_casIntArray ::
     forall ix. (Show (Array P ix Int), Arbitrary ix, Index ix)
  => Property
prop_casIntArray :: Property
prop_casIntArray =
  (Array P ix Ix1 -> ix -> Ix1 -> IO ()) -> Property
forall prop. Testable prop => prop -> Property
property ((Array P ix Ix1 -> ix -> Ix1 -> IO ()) -> Property)
-> (Array P ix Ix1 -> ix -> Ix1 -> IO ()) -> Property
forall a b. (a -> b) -> a -> b
$ \Array P ix Ix1
arr (ix
ix :: ix) (Ix1
e :: Int) -> do
    MArray RealWorld P ix Ix1
marr <- Array P ix Ix1 -> IO (MArray (PrimState IO) P ix Ix1)
forall r ix e (m :: * -> *).
(Mutable r ix e, PrimMonad m) =>
Array r ix e -> m (MArray (PrimState m) r ix e)
unsafeThaw Array P ix Ix1
arr
    Maybe Ix1
mx <- MArray (PrimState IO) P ix Ix1 -> ix -> IO (Maybe Ix1)
forall r ix e (m :: * -> *).
(Mutable r ix e, PrimMonad m) =>
MArray (PrimState m) r ix e -> ix -> m (Maybe e)
A.read MArray RealWorld P ix Ix1
MArray (PrimState IO) P ix Ix1
marr ix
ix
    case Maybe Ix1
mx of
      Maybe Ix1
Nothing -> MArray (PrimState IO) P ix Ix1
-> ix -> Ix1 -> Ix1 -> IO (Maybe Ix1)
forall ix (m :: * -> *).
(Index ix, PrimMonad m) =>
MArray (PrimState m) P ix Ix1 -> ix -> Ix1 -> Ix1 -> m (Maybe Ix1)
casIntArray MArray RealWorld P ix Ix1
MArray (PrimState IO) P ix Ix1
marr ix
ix Ix1
e Ix1
e IO (Maybe Ix1) -> Maybe Ix1 -> IO ()
forall a. (HasCallStack, Show a, Eq a) => IO a -> a -> IO ()
`shouldReturn` Maybe Ix1
forall a. Maybe a
Nothing
      Just Ix1
x -> do
        MArray (PrimState IO) P ix Ix1
-> ix -> Ix1 -> Ix1 -> IO (Maybe Ix1)
forall ix (m :: * -> *).
(Index ix, PrimMonad m) =>
MArray (PrimState m) P ix Ix1 -> ix -> Ix1 -> Ix1 -> m (Maybe Ix1)
casIntArray MArray RealWorld P ix Ix1
MArray (PrimState IO) P ix Ix1
marr ix
ix Ix1
x Ix1
e IO (Maybe Ix1) -> Maybe Ix1 -> IO ()
forall a. (HasCallStack, Show a, Eq a) => IO a -> a -> IO ()
`shouldReturn` Maybe Ix1
mx
        MArray (PrimState IO) P ix Ix1 -> ix -> IO Ix1
forall r ix e (m :: * -> *).
(Mutable r ix e, PrimMonad m, MonadThrow m) =>
MArray (PrimState m) r ix e -> ix -> m e
A.readM MArray RealWorld P ix Ix1
MArray (PrimState IO) P ix Ix1
marr ix
ix IO Ix1 -> Ix1 -> IO ()
forall a. (HasCallStack, Show a, Eq a) => IO a -> a -> IO ()
`shouldReturn` Ix1
e


atomicIntSpec ::
     forall ix. (Show (Array P ix Int), Arbitrary ix, Index ix)
  => Spec
atomicIntSpec :: Spec
atomicIntSpec =
  String -> Spec -> Spec
forall a. HasCallStack => String -> SpecWith a -> SpecWith a
describe String
"Atomic Int Operations" (Spec -> Spec) -> Spec -> Spec
forall a b. (a -> b) -> a -> b
$ do
    String -> Property -> SpecWith (Arg Property)
forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"atomicModifyIntArrayMany" (Property -> SpecWith (Arg Property))
-> Property -> SpecWith (Arg Property)
forall a b. (a -> b) -> a -> b
$ (Show (Array P ix Ix1), Arbitrary ix, Index ix) => Property
forall ix.
(Show (Array P ix Ix1), Arbitrary ix, Index ix) =>
Property
prop_atomicModifyIntArrayMany @ix
    String -> Property -> SpecWith (Arg Property)
forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"atomicReadIntArray" (Property -> SpecWith (Arg Property))
-> Property -> SpecWith (Arg Property)
forall a b. (a -> b) -> a -> b
$ (Show (Array P ix Ix1), Arbitrary ix, Index ix) => Property
forall ix.
(Show (Array P ix Ix1), Arbitrary ix, Index ix) =>
Property
prop_atomicReadIntArray @ix
    String -> Property -> SpecWith (Arg Property)
forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"atomicWriteIntArray" (Property -> SpecWith (Arg Property))
-> Property -> SpecWith (Arg Property)
forall a b. (a -> b) -> a -> b
$ (Show (Array P ix Ix1), Arbitrary ix, Index ix) => Property
forall ix.
(Show (Array P ix Ix1), Arbitrary ix, Index ix) =>
Property
prop_atomicWriteIntArray @ix
    String -> Property -> SpecWith (Arg Property)
forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"atomicAddIntArray" (Property -> SpecWith (Arg Property))
-> Property -> SpecWith (Arg Property)
forall a b. (a -> b) -> a -> b
$ (Ix1 -> Ix1 -> Ix1)
-> (forall (m :: * -> *).
    PrimMonad m =>
    MArray (PrimState m) P ix Ix1 -> ix -> Ix1 -> m (Maybe Ix1))
-> Property
forall ix.
(Show (Array P ix Ix1), Arbitrary ix, Index ix) =>
(Ix1 -> Ix1 -> Ix1)
-> (forall (m :: * -> *).
    PrimMonad m =>
    MArray (PrimState m) P ix Ix1 -> ix -> Ix1 -> m (Maybe Ix1))
-> Property
prop_atomicOpIntArray @ix Ix1 -> Ix1 -> Ix1
forall a. Num a => a -> a -> a
(+) forall ix (m :: * -> *).
(Index ix, PrimMonad m) =>
MArray (PrimState m) P ix Ix1 -> ix -> Ix1 -> m (Maybe Ix1)
forall (m :: * -> *).
PrimMonad m =>
MArray (PrimState m) P ix Ix1 -> ix -> Ix1 -> m (Maybe Ix1)
atomicAddIntArray
    String -> Property -> SpecWith (Arg Property)
forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"atomicSubIntArray" (Property -> SpecWith (Arg Property))
-> Property -> SpecWith (Arg Property)
forall a b. (a -> b) -> a -> b
$ (Ix1 -> Ix1 -> Ix1)
-> (forall (m :: * -> *).
    PrimMonad m =>
    MArray (PrimState m) P ix Ix1 -> ix -> Ix1 -> m (Maybe Ix1))
-> Property
forall ix.
(Show (Array P ix Ix1), Arbitrary ix, Index ix) =>
(Ix1 -> Ix1 -> Ix1)
-> (forall (m :: * -> *).
    PrimMonad m =>
    MArray (PrimState m) P ix Ix1 -> ix -> Ix1 -> m (Maybe Ix1))
-> Property
prop_atomicOpIntArray @ix (-) forall ix (m :: * -> *).
(Index ix, PrimMonad m) =>
MArray (PrimState m) P ix Ix1 -> ix -> Ix1 -> m (Maybe Ix1)
forall (m :: * -> *).
PrimMonad m =>
MArray (PrimState m) P ix Ix1 -> ix -> Ix1 -> m (Maybe Ix1)
atomicSubIntArray
    String -> Property -> SpecWith (Arg Property)
forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"atomicAndIntArray" (Property -> SpecWith (Arg Property))
-> Property -> SpecWith (Arg Property)
forall a b. (a -> b) -> a -> b
$ (Ix1 -> Ix1 -> Ix1)
-> (forall (m :: * -> *).
    PrimMonad m =>
    MArray (PrimState m) P ix Ix1 -> ix -> Ix1 -> m (Maybe Ix1))
-> Property
forall ix.
(Show (Array P ix Ix1), Arbitrary ix, Index ix) =>
(Ix1 -> Ix1 -> Ix1)
-> (forall (m :: * -> *).
    PrimMonad m =>
    MArray (PrimState m) P ix Ix1 -> ix -> Ix1 -> m (Maybe Ix1))
-> Property
prop_atomicOpIntArray @ix Ix1 -> Ix1 -> Ix1
forall a. Bits a => a -> a -> a
(.&.) forall ix (m :: * -> *).
(Index ix, PrimMonad m) =>
MArray (PrimState m) P ix Ix1 -> ix -> Ix1 -> m (Maybe Ix1)
forall (m :: * -> *).
PrimMonad m =>
MArray (PrimState m) P ix Ix1 -> ix -> Ix1 -> m (Maybe Ix1)
atomicAndIntArray
    String -> Property -> SpecWith (Arg Property)
forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"atomicNandIntArray" (Property -> SpecWith (Arg Property))
-> Property -> SpecWith (Arg Property)
forall a b. (a -> b) -> a -> b
$
      (Ix1 -> Ix1 -> Ix1)
-> (forall (m :: * -> *).
    PrimMonad m =>
    MArray (PrimState m) P ix Ix1 -> ix -> Ix1 -> m (Maybe Ix1))
-> Property
forall ix.
(Show (Array P ix Ix1), Arbitrary ix, Index ix) =>
(Ix1 -> Ix1 -> Ix1)
-> (forall (m :: * -> *).
    PrimMonad m =>
    MArray (PrimState m) P ix Ix1 -> ix -> Ix1 -> m (Maybe Ix1))
-> Property
prop_atomicOpIntArray @ix (\Ix1
x Ix1
y -> Ix1 -> Ix1
forall a. Bits a => a -> a
complement (Ix1
x Ix1 -> Ix1 -> Ix1
forall a. Bits a => a -> a -> a
.&. Ix1
y)) forall ix (m :: * -> *).
(Index ix, PrimMonad m) =>
MArray (PrimState m) P ix Ix1 -> ix -> Ix1 -> m (Maybe Ix1)
forall (m :: * -> *).
PrimMonad m =>
MArray (PrimState m) P ix Ix1 -> ix -> Ix1 -> m (Maybe Ix1)
atomicNandIntArray
    String -> Property -> SpecWith (Arg Property)
forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"atomicOrIntArray" (Property -> SpecWith (Arg Property))
-> Property -> SpecWith (Arg Property)
forall a b. (a -> b) -> a -> b
$ (Ix1 -> Ix1 -> Ix1)
-> (forall (m :: * -> *).
    PrimMonad m =>
    MArray (PrimState m) P ix Ix1 -> ix -> Ix1 -> m (Maybe Ix1))
-> Property
forall ix.
(Show (Array P ix Ix1), Arbitrary ix, Index ix) =>
(Ix1 -> Ix1 -> Ix1)
-> (forall (m :: * -> *).
    PrimMonad m =>
    MArray (PrimState m) P ix Ix1 -> ix -> Ix1 -> m (Maybe Ix1))
-> Property
prop_atomicOpIntArray @ix Ix1 -> Ix1 -> Ix1
forall a. Bits a => a -> a -> a
(.|.) forall ix (m :: * -> *).
(Index ix, PrimMonad m) =>
MArray (PrimState m) P ix Ix1 -> ix -> Ix1 -> m (Maybe Ix1)
forall (m :: * -> *).
PrimMonad m =>
MArray (PrimState m) P ix Ix1 -> ix -> Ix1 -> m (Maybe Ix1)
atomicOrIntArray
    String -> Property -> SpecWith (Arg Property)
forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"atomicXorIntArray" (Property -> SpecWith (Arg Property))
-> Property -> SpecWith (Arg Property)
forall a b. (a -> b) -> a -> b
$ (Ix1 -> Ix1 -> Ix1)
-> (forall (m :: * -> *).
    PrimMonad m =>
    MArray (PrimState m) P ix Ix1 -> ix -> Ix1 -> m (Maybe Ix1))
-> Property
forall ix.
(Show (Array P ix Ix1), Arbitrary ix, Index ix) =>
(Ix1 -> Ix1 -> Ix1)
-> (forall (m :: * -> *).
    PrimMonad m =>
    MArray (PrimState m) P ix Ix1 -> ix -> Ix1 -> m (Maybe Ix1))
-> Property
prop_atomicOpIntArray @ix Ix1 -> Ix1 -> Ix1
forall a. Bits a => a -> a -> a
xor forall ix (m :: * -> *).
(Index ix, PrimMonad m) =>
MArray (PrimState m) P ix Ix1 -> ix -> Ix1 -> m (Maybe Ix1)
forall (m :: * -> *).
PrimMonad m =>
MArray (PrimState m) P ix Ix1 -> ix -> Ix1 -> m (Maybe Ix1)
atomicXorIntArray
    String -> Property -> SpecWith (Arg Property)
forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"casIntArray" (Property -> SpecWith (Arg Property))
-> Property -> SpecWith (Arg Property)
forall a b. (a -> b) -> a -> b
$ (Show (Array P ix Ix1), Arbitrary ix, Index ix) => Property
forall ix.
(Show (Array P ix Ix1), Arbitrary ix, Index ix) =>
Property
prop_casIntArray @ix