-- |
-- Module:      Test.QuickCheck.Classes.MVector
-- Copyright:   (c) 2019 Andrew Lelechenko
-- Licence:     BSD3
--

{-# LANGUAGE CPP #-}
{-# LANGUAGE ScopedTypeVariables #-}

{-# OPTIONS_GHC -Wall #-}

#if !HAVE_VECTOR
module Test.QuickCheck.Classes.MVector where
#else

module Test.QuickCheck.Classes.MVector
  ( muvectorLaws
  ) where

import Control.Applicative
import Control.Monad (when)
import Control.Monad.ST
import Data.Functor
import Data.Proxy (Proxy)
import qualified Data.Vector.Generic.Mutable as MU (basicInitialize)
import qualified Data.Vector.Unboxed.Mutable as MU

import Test.QuickCheck hiding ((.&.))
import Test.QuickCheck.Property (Property)

import Test.QuickCheck.Classes.Internal (Laws(..))

-- | Test that a 'Vector.Unboxed.MVector' instance obey several laws.
muvectorLaws :: (Eq a, MU.Unbox a, Arbitrary a, Show a) => Proxy a -> Laws
muvectorLaws :: forall a. (Eq a, Unbox a, Arbitrary a, Show a) => Proxy a -> Laws
muvectorLaws Proxy a
p = String -> [(String, Property)] -> Laws
Laws String
"Vector.Unboxed.MVector"
  [ (String
"New-Length", Proxy a -> Property
forall a.
(Eq a, Unbox a, Arbitrary a, Show a) =>
Proxy a -> Property
newLength Proxy a
p)
  , (String
"Replicate-Length", Proxy a -> Property
forall a.
(Eq a, Unbox a, Arbitrary a, Show a) =>
Proxy a -> Property
replicateLength Proxy a
p)
  , (String
"Slice-Length", Proxy a -> Property
forall a.
(Eq a, Unbox a, Arbitrary a, Show a) =>
Proxy a -> Property
sliceLength Proxy a
p)
  , (String
"Grow-Length", Proxy a -> Property
forall a.
(Eq a, Unbox a, Arbitrary a, Show a) =>
Proxy a -> Property
growLength Proxy a
p)

  , (String
"Write-Read", Proxy a -> Property
forall a.
(Eq a, Unbox a, Arbitrary a, Show a) =>
Proxy a -> Property
writeRead Proxy a
p)
  , (String
"Set-Read", Proxy a -> Property
forall a.
(Eq a, Unbox a, Arbitrary a, Show a) =>
Proxy a -> Property
setRead Proxy a
p)
  , (String
"Sliced-Set-Read", Proxy a -> Property
forall a.
(Eq a, Unbox a, Arbitrary a, Show a) =>
Proxy a -> Property
slicedSetRead Proxy a
p)
  , (String
"Replicate-Read", Proxy a -> Property
forall a.
(Eq a, Unbox a, Arbitrary a, Show a) =>
Proxy a -> Property
replicateRead Proxy a
p)

  , (String
"Slice-Overlaps", Proxy a -> Property
forall a.
(Eq a, Unbox a, Arbitrary a, Show a) =>
Proxy a -> Property
sliceOverlaps Proxy a
p)
  , (String
"Slice-Copy", Proxy a -> Property
forall a.
(Eq a, Unbox a, Arbitrary a, Show a) =>
Proxy a -> Property
sliceCopy Proxy a
p)
  , (String
"Slice-Move", Proxy a -> Property
forall a.
(Eq a, Unbox a, Arbitrary a, Show a) =>
Proxy a -> Property
sliceMove Proxy a
p)

  , (String
"Write-Copy-Read", Proxy a -> Property
forall a.
(Eq a, Unbox a, Arbitrary a, Show a) =>
Proxy a -> Property
writeCopyRead Proxy a
p)
  , (String
"Write-Move-Read", Proxy a -> Property
forall a.
(Eq a, Unbox a, Arbitrary a, Show a) =>
Proxy a -> Property
writeMoveRead Proxy a
p)
  , (String
"Write-Grow-Read", Proxy a -> Property
forall a.
(Eq a, Unbox a, Arbitrary a, Show a) =>
Proxy a -> Property
writeGrowRead Proxy a
p)
  , (String
"Sliced-Write-Copy-Read", Proxy a -> Property
forall a.
(Eq a, Unbox a, Arbitrary a, Show a) =>
Proxy a -> Property
slicedWriteCopyRead Proxy a
p)
  , (String
"Sliced-Write-Move-Read", Proxy a -> Property
forall a.
(Eq a, Unbox a, Arbitrary a, Show a) =>
Proxy a -> Property
slicedWriteMoveRead Proxy a
p)
  , (String
"Sliced-Write-Grow-Read", Proxy a -> Property
forall a.
(Eq a, Unbox a, Arbitrary a, Show a) =>
Proxy a -> Property
slicedWriteGrowRead Proxy a
p)

  , (String
"Write-InitializeAround-Read", Proxy a -> Property
forall a.
(Eq a, Unbox a, Arbitrary a, Show a) =>
Proxy a -> Property
writeInitializeAroundRead Proxy a
p)
  , (String
"Write-ClearAround-Read", Proxy a -> Property
forall a.
(Eq a, Unbox a, Arbitrary a, Show a) =>
Proxy a -> Property
writeClearAroundRead Proxy a
p)
  , (String
"Write-SetAround-Read", Proxy a -> Property
forall a.
(Eq a, Unbox a, Arbitrary a, Show a) =>
Proxy a -> Property
writeSetAroundRead Proxy a
p)
  , (String
"Write-WriteAround-Read", Proxy a -> Property
forall a.
(Eq a, Unbox a, Arbitrary a, Show a) =>
Proxy a -> Property
writeWriteAroundRead Proxy a
p)
  , (String
"Write-CopyAround-Read", Proxy a -> Property
forall a.
(Eq a, Unbox a, Arbitrary a, Show a) =>
Proxy a -> Property
writeCopyAroundRead Proxy a
p)
  , (String
"Write-MoveAround-Read", Proxy a -> Property
forall a.
(Eq a, Unbox a, Arbitrary a, Show a) =>
Proxy a -> Property
writeMoveAroundRead Proxy a
p)

  , (String
"Write-InitializeBetween-Read", Proxy a -> Property
forall a.
(Eq a, Unbox a, Arbitrary a, Show a) =>
Proxy a -> Property
writeInitializeBetweenRead Proxy a
p)
  , (String
"Write-ClearBetween-Read", Proxy a -> Property
forall a.
(Eq a, Unbox a, Arbitrary a, Show a) =>
Proxy a -> Property
writeClearBetweenRead Proxy a
p)
  , (String
"Write-SetBetween-Read", Proxy a -> Property
forall a.
(Eq a, Unbox a, Arbitrary a, Show a) =>
Proxy a -> Property
writeSetBetweenRead Proxy a
p)
  , (String
"Write-CopyBetween-Read", Proxy a -> Property
forall a.
(Eq a, Unbox a, Arbitrary a, Show a) =>
Proxy a -> Property
writeCopyBetweenRead Proxy a
p)
  , (String
"Write-MoveBetween-Read", Proxy a -> Property
forall a.
(Eq a, Unbox a, Arbitrary a, Show a) =>
Proxy a -> Property
writeMoveBetweenRead Proxy a
p)
  ]

-------------------------------------------------------------------------------
-- Length

newLength :: forall a. (Eq a, MU.Unbox a, Arbitrary a, Show a) => Proxy a -> Property
newLength :: forall a.
(Eq a, Unbox a, Arbitrary a, Show a) =>
Proxy a -> Property
newLength Proxy a
_ = (NonNegative Int -> Property) -> Property
forall prop. Testable prop => prop -> Property
property ((NonNegative Int -> Property) -> Property)
-> (NonNegative Int -> Property) -> Property
forall a b. (a -> b) -> a -> b
$ \(NonNegative Int
len) -> do
  (Int -> Int -> Property
forall a. (Eq a, Show a) => a -> a -> Property
=== Int
len) ((forall s. ST s Int) -> Int
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s Int) -> Int) -> (forall s. ST s Int) -> Int
forall a b. (a -> b) -> a -> b
$ MVector s a -> Int
forall a s. Unbox a => MVector s a -> Int
MU.length (MVector s a -> Int) -> ST s (MVector s a) -> ST s Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Int -> ST s (MVector (PrimState (ST s)) a)
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
Int -> m (MVector (PrimState m) a)
MU.new Int
len :: ST s (MU.MVector s a)))

replicateLength :: forall a. (Eq a, MU.Unbox a, Arbitrary a, Show a) => Proxy a -> Property
replicateLength :: forall a.
(Eq a, Unbox a, Arbitrary a, Show a) =>
Proxy a -> Property
replicateLength Proxy a
_ = (a -> NonNegative Int -> Property) -> Property
forall prop. Testable prop => prop -> Property
property ((a -> NonNegative Int -> Property) -> Property)
-> (a -> NonNegative Int -> Property) -> Property
forall a b. (a -> b) -> a -> b
$ \(a
a :: a) (NonNegative Int
len) -> do
  (Int -> Int -> Property
forall a. (Eq a, Show a) => a -> a -> Property
=== Int
len) ((forall s. ST s Int) -> Int
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s Int) -> Int) -> (forall s. ST s Int) -> Int
forall a b. (a -> b) -> a -> b
$ MVector s a -> Int
forall a s. Unbox a => MVector s a -> Int
MU.length (MVector s a -> Int) -> ST s (MVector s a) -> ST s Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> a -> ST s (MVector (PrimState (ST s)) a)
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
Int -> a -> m (MVector (PrimState m) a)
MU.replicate Int
len a
a)

sliceLength :: forall a. (Eq a, MU.Unbox a, Arbitrary a, Show a) => Proxy a -> Property
sliceLength :: forall a.
(Eq a, Unbox a, Arbitrary a, Show a) =>
Proxy a -> Property
sliceLength Proxy a
_ = (NonNegative Int -> NonNegative Int -> Positive Int -> Property)
-> Property
forall prop. Testable prop => prop -> Property
property ((NonNegative Int -> NonNegative Int -> Positive Int -> Property)
 -> Property)
-> (NonNegative Int -> NonNegative Int -> Positive Int -> Property)
-> Property
forall a b. (a -> b) -> a -> b
$ \(NonNegative Int
ix) (NonNegative Int
subLen) (Positive Int
excess) -> do
  (Int -> Int -> Property
forall a. (Eq a, Show a) => a -> a -> Property
=== Int
subLen) ((forall s. ST s Int) -> Int
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s Int) -> Int) -> (forall s. ST s Int) -> Int
forall a b. (a -> b) -> a -> b
$ MVector s a -> Int
forall a s. Unbox a => MVector s a -> Int
MU.length (MVector s a -> Int)
-> (MVector s a -> MVector s a) -> MVector s a -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Int -> MVector s a -> MVector s a
forall a s. Unbox a => Int -> Int -> MVector s a -> MVector s a
MU.slice Int
ix Int
subLen (MVector s a -> Int) -> ST s (MVector s a) -> ST s Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Int -> ST s (MVector (PrimState (ST s)) a)
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
Int -> m (MVector (PrimState m) a)
MU.new (Int
ix Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
subLen Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
excess) :: ST s (MU.MVector s a)))

growLength :: forall a. (Eq a, MU.Unbox a, Arbitrary a, Show a) => Proxy a -> Property
growLength :: forall a.
(Eq a, Unbox a, Arbitrary a, Show a) =>
Proxy a -> Property
growLength Proxy a
_ = (Positive Int -> Positive Int -> Property) -> Property
forall prop. Testable prop => prop -> Property
property ((Positive Int -> Positive Int -> Property) -> Property)
-> (Positive Int -> Positive Int -> Property) -> Property
forall a b. (a -> b) -> a -> b
$ \(Positive Int
len) (Positive Int
by) -> do
  (Int -> Int -> Property
forall a. (Eq a, Show a) => a -> a -> Property
=== Int
len Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
by) (Int -> Property) -> Int -> Property
forall a b. (a -> b) -> a -> b
$ (forall s. ST s Int) -> Int
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s Int) -> Int) -> (forall s. ST s Int) -> Int
forall a b. (a -> b) -> a -> b
$ do
    arr <- Int -> ST s (MVector (PrimState (ST s)) a)
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
Int -> m (MVector (PrimState m) a)
MU.new Int
len :: ST s (MU.MVector s a)
    MU.length <$> MU.grow arr by

-------------------------------------------------------------------------------
-- Read

writeRead :: forall a. (Eq a, MU.Unbox a, Arbitrary a, Show a) => Proxy a -> Property
writeRead :: forall a.
(Eq a, Unbox a, Arbitrary a, Show a) =>
Proxy a -> Property
writeRead Proxy a
_ = (a -> NonNegative Int -> Positive Int -> Property) -> Property
forall prop. Testable prop => prop -> Property
property ((a -> NonNegative Int -> Positive Int -> Property) -> Property)
-> (a -> NonNegative Int -> Positive Int -> Property) -> Property
forall a b. (a -> b) -> a -> b
$ \(a
a :: a) (NonNegative Int
ix) (Positive Int
excess) -> do
  (a -> a -> Property
forall a. (Eq a, Show a) => a -> a -> Property
=== a
a) (a -> Property) -> a -> Property
forall a b. (a -> b) -> a -> b
$ (forall s. ST s a) -> a
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s a) -> a) -> (forall s. ST s a) -> a
forall a b. (a -> b) -> a -> b
$ do
    arr <- Int -> ST s (MVector (PrimState (ST s)) a)
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
Int -> m (MVector (PrimState m) a)
MU.new (Int
ix Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
excess)
    MU.write arr ix a
    MU.read arr ix

setRead :: forall a. (Eq a, MU.Unbox a, Arbitrary a, Show a) => Proxy a -> Property
setRead :: forall a.
(Eq a, Unbox a, Arbitrary a, Show a) =>
Proxy a -> Property
setRead Proxy a
_ = (a -> NonNegative Int -> Positive Int -> Property) -> Property
forall prop. Testable prop => prop -> Property
property ((a -> NonNegative Int -> Positive Int -> Property) -> Property)
-> (a -> NonNegative Int -> Positive Int -> Property) -> Property
forall a b. (a -> b) -> a -> b
$ \(a
a :: a) (NonNegative Int
ix) (Positive Int
excess) -> do
  (a -> a -> Property
forall a. (Eq a, Show a) => a -> a -> Property
=== a
a) (a -> Property) -> a -> Property
forall a b. (a -> b) -> a -> b
$ (forall s. ST s a) -> a
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s a) -> a) -> (forall s. ST s a) -> a
forall a b. (a -> b) -> a -> b
$ do
    arr <- Int -> ST s (MVector (PrimState (ST s)) a)
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
Int -> m (MVector (PrimState m) a)
MU.new (Int
ix Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
excess)
    MU.set arr a
    MU.read arr ix

slicedSetRead :: forall a. (Eq a, MU.Unbox a, Arbitrary a, Show a) => Proxy a -> Property
slicedSetRead :: forall a.
(Eq a, Unbox a, Arbitrary a, Show a) =>
Proxy a -> Property
slicedSetRead Proxy a
_ = (a
 -> NonNegative Int
 -> Positive Int
 -> NonNegative Int
 -> NonNegative Int
 -> Property)
-> Property
forall prop. Testable prop => prop -> Property
property ((a
  -> NonNegative Int
  -> Positive Int
  -> NonNegative Int
  -> NonNegative Int
  -> Property)
 -> Property)
-> (a
    -> NonNegative Int
    -> Positive Int
    -> NonNegative Int
    -> NonNegative Int
    -> Property)
-> Property
forall a b. (a -> b) -> a -> b
$ \(a
a :: a) (NonNegative Int
ix) (Positive Int
excess) NonNegative Int
before NonNegative Int
after -> do
  (a -> a -> Property
forall a. (Eq a, Show a) => a -> a -> Property
=== a
a) (a -> Property) -> a -> Property
forall a b. (a -> b) -> a -> b
$ (forall s. ST s a) -> a
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s a) -> a) -> (forall s. ST s a) -> a
forall a b. (a -> b) -> a -> b
$ do
    arr <- NonNegative Int -> NonNegative Int -> Int -> ST s (MVector s a)
forall a s.
Unbox a =>
NonNegative Int -> NonNegative Int -> Int -> ST s (MVector s a)
newSlice NonNegative Int
before NonNegative Int
after (Int
ix Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
excess)
    MU.set arr a
    MU.read arr ix

replicateRead :: forall a. (Eq a, MU.Unbox a, Arbitrary a, Show a) => Proxy a -> Property
replicateRead :: forall a.
(Eq a, Unbox a, Arbitrary a, Show a) =>
Proxy a -> Property
replicateRead Proxy a
_ = (a -> NonNegative Int -> Positive Int -> Property) -> Property
forall prop. Testable prop => prop -> Property
property ((a -> NonNegative Int -> Positive Int -> Property) -> Property)
-> (a -> NonNegative Int -> Positive Int -> Property) -> Property
forall a b. (a -> b) -> a -> b
$ \(a
a :: a) (NonNegative Int
ix) (Positive Int
excess) -> do
  (a -> a -> Property
forall a. (Eq a, Show a) => a -> a -> Property
=== a
a) (a -> Property) -> a -> Property
forall a b. (a -> b) -> a -> b
$ (forall s. ST s a) -> a
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s a) -> a) -> (forall s. ST s a) -> a
forall a b. (a -> b) -> a -> b
$ do
    arr <- Int -> a -> ST s (MVector (PrimState (ST s)) a)
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
Int -> a -> m (MVector (PrimState m) a)
MU.replicate (Int
ix Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
excess) a
a
    MU.read arr ix

-------------------------------------------------------------------------------
-- Overlaps

sliceOverlaps :: forall a. (Eq a, MU.Unbox a, Arbitrary a, Show a) => Proxy a -> Property
sliceOverlaps :: forall a.
(Eq a, Unbox a, Arbitrary a, Show a) =>
Proxy a -> Property
sliceOverlaps Proxy a
_ = (NonNegative Int
 -> NonNegative Int
 -> NonNegative Int
 -> NonNegative Int
 -> NonNegative Int
 -> Property)
-> Property
forall prop. Testable prop => prop -> Property
property ((NonNegative Int
  -> NonNegative Int
  -> NonNegative Int
  -> NonNegative Int
  -> NonNegative Int
  -> Property)
 -> Property)
-> (NonNegative Int
    -> NonNegative Int
    -> NonNegative Int
    -> NonNegative Int
    -> NonNegative Int
    -> Property)
-> Property
forall a b. (a -> b) -> a -> b
$ \(NonNegative Int
i) (NonNegative Int
ij) (NonNegative Int
jk) (NonNegative Int
kl) (NonNegative Int
lm) -> do
  let j :: Int
j = Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
ij
      k :: Int
k = Int
j Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
jk
      l :: Int
l = Int
k Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
kl
      m :: Int
m = Int
l Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
lm
  Bool -> Property
forall prop. Testable prop => prop -> Property
property (Bool -> Property) -> Bool -> Property
forall a b. (a -> b) -> a -> b
$ (forall s. ST s Bool) -> Bool
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s Bool) -> Bool) -> (forall s. ST s Bool) -> Bool
forall a b. (a -> b) -> a -> b
$ do
    arr <- Int -> ST s (MVector (PrimState (ST s)) a)
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
Int -> m (MVector (PrimState m) a)
MU.new (Int
m Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) :: ST s (MU.MVector s a)
    let slice1 = Int -> Int -> MVector s a -> MVector s a
forall a s. Unbox a => Int -> Int -> MVector s a -> MVector s a
MU.slice Int
i (Int
k Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) MVector s a
arr
        slice2 = Int -> Int -> MVector s a -> MVector s a
forall a s. Unbox a => Int -> Int -> MVector s a -> MVector s a
MU.slice Int
j (Int
l Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
j Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) MVector s a
arr
    pure $ MU.overlaps slice1 slice2

sliceCopy :: forall a. (Eq a, MU.Unbox a, Arbitrary a, Show a) => Proxy a -> Property
sliceCopy :: forall a.
(Eq a, Unbox a, Arbitrary a, Show a) =>
Proxy a -> Property
sliceCopy Proxy a
_ = (a
 -> NonNegative Int
 -> NonNegative Int
 -> Positive Int
 -> NonNegative Int
 -> NonNegative Int
 -> Property)
-> Property
forall prop. Testable prop => prop -> Property
property ((a
  -> NonNegative Int
  -> NonNegative Int
  -> Positive Int
  -> NonNegative Int
  -> NonNegative Int
  -> Property)
 -> Property)
-> (a
    -> NonNegative Int
    -> NonNegative Int
    -> Positive Int
    -> NonNegative Int
    -> NonNegative Int
    -> Property)
-> Property
forall a b. (a -> b) -> a -> b
$ \(a
a :: a) (NonNegative Int
i) (NonNegative Int
ix) (Positive Int
excess) (NonNegative Int
ij) (NonNegative Int
jk) -> do
  let j :: Int
j = Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
ix Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
excess Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
ij
      k :: Int
k = Int
j Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
ix Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
excess Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
jk
  (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
    arr <- Int -> ST s (MVector (PrimState (ST s)) a)
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
Int -> m (MVector (PrimState m) a)
MU.new Int
k :: ST s (MU.MVector s a)
    let src = Int -> Int -> MVector s a -> MVector s a
forall a s. Unbox a => Int -> Int -> MVector s a -> MVector s a
MU.slice Int
i (Int
ix Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
excess) MVector s a
arr
        dst = Int -> Int -> MVector s a -> MVector s a
forall a s. Unbox a => Int -> Int -> MVector s a -> MVector s a
MU.slice Int
j (Int
ix Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
excess) MVector s a
arr
    if MU.overlaps src dst then pure (property True) else do
      MU.write src ix a
      MU.copy dst src
      valSrc <- MU.read src ix
      valDst <- MU.read dst ix
      pure (valSrc === a .&&. valDst === a)

sliceMove :: forall a. (Eq a, MU.Unbox a, Arbitrary a, Show a) => Proxy a -> Property
sliceMove :: forall a.
(Eq a, Unbox a, Arbitrary a, Show a) =>
Proxy a -> Property
sliceMove Proxy a
_ = (a
 -> NonNegative Int
 -> NonNegative Int
 -> Positive Int
 -> NonNegative Int
 -> NonNegative Int
 -> Property)
-> Property
forall prop. Testable prop => prop -> Property
property ((a
  -> NonNegative Int
  -> NonNegative Int
  -> Positive Int
  -> NonNegative Int
  -> NonNegative Int
  -> Property)
 -> Property)
-> (a
    -> NonNegative Int
    -> NonNegative Int
    -> Positive Int
    -> NonNegative Int
    -> NonNegative Int
    -> Property)
-> Property
forall a b. (a -> b) -> a -> b
$ \(a
a :: a) (NonNegative Int
i) (NonNegative Int
ix) (Positive Int
excess) (NonNegative Int
ij) (NonNegative Int
jk) -> do
  let j :: Int
j = Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
ix Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
excess Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
ij
      k :: Int
k = Int
j Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
ix Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
excess Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
jk
  (a -> a -> Property
forall a. (Eq a, Show a) => a -> a -> Property
=== a
a) (a -> Property) -> a -> Property
forall a b. (a -> b) -> a -> b
$ (forall s. ST s a) -> a
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s a) -> a) -> (forall s. ST s a) -> a
forall a b. (a -> b) -> a -> b
$ do
    arr <- Int -> ST s (MVector (PrimState (ST s)) a)
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
Int -> m (MVector (PrimState m) a)
MU.new Int
k :: ST s (MU.MVector s a)
    let src = Int -> Int -> MVector s a -> MVector s a
forall a s. Unbox a => Int -> Int -> MVector s a -> MVector s a
MU.slice Int
i (Int
ix Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
excess) MVector s a
arr
        dst = Int -> Int -> MVector s a -> MVector s a
forall a s. Unbox a => Int -> Int -> MVector s a -> MVector s a
MU.slice Int
j (Int
ix Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
excess) MVector s a
arr
    MU.write src ix a
    MU.move dst src
    MU.read dst ix

-------------------------------------------------------------------------------
-- Write + copy/move/grow

writeCopyRead :: forall a. (Eq a, MU.Unbox a, Arbitrary a, Show a) => Proxy a -> Property
writeCopyRead :: forall a.
(Eq a, Unbox a, Arbitrary a, Show a) =>
Proxy a -> Property
writeCopyRead Proxy a
_ = (a -> NonNegative Int -> Positive Int -> Property) -> Property
forall prop. Testable prop => prop -> Property
property ((a -> NonNegative Int -> Positive Int -> Property) -> Property)
-> (a -> NonNegative Int -> Positive Int -> Property) -> Property
forall a b. (a -> b) -> a -> b
$ \(a
a :: a) (NonNegative Int
ix) (Positive Int
excess) -> do
  (a -> a -> Property
forall a. (Eq a, Show a) => a -> a -> Property
=== a
a) (a -> Property) -> a -> Property
forall a b. (a -> b) -> a -> b
$ (forall s. ST s a) -> a
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s a) -> a) -> (forall s. ST s a) -> a
forall a b. (a -> b) -> a -> b
$ do
    src <- Int -> ST s (MVector (PrimState (ST s)) a)
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
Int -> m (MVector (PrimState m) a)
MU.new (Int
ix Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
excess)
    MU.write src ix a
    dst <- MU.new (ix + excess)
    MU.copy dst src
    MU.clear src
    MU.read dst ix

writeMoveRead :: forall a. (Eq a, MU.Unbox a, Arbitrary a, Show a) => Proxy a -> Property
writeMoveRead :: forall a.
(Eq a, Unbox a, Arbitrary a, Show a) =>
Proxy a -> Property
writeMoveRead Proxy a
_ = (a -> NonNegative Int -> Positive Int -> Property) -> Property
forall prop. Testable prop => prop -> Property
property ((a -> NonNegative Int -> Positive Int -> Property) -> Property)
-> (a -> NonNegative Int -> Positive Int -> Property) -> Property
forall a b. (a -> b) -> a -> b
$ \(a
a :: a) (NonNegative Int
ix) (Positive Int
excess) -> do
  (a -> a -> Property
forall a. (Eq a, Show a) => a -> a -> Property
=== a
a) (a -> Property) -> a -> Property
forall a b. (a -> b) -> a -> b
$ (forall s. ST s a) -> a
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s a) -> a) -> (forall s. ST s a) -> a
forall a b. (a -> b) -> a -> b
$ do
    src <- Int -> ST s (MVector (PrimState (ST s)) a)
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
Int -> m (MVector (PrimState m) a)
MU.new (Int
ix Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
excess)
    MU.write src ix a
    dst <- MU.new (ix + excess)
    MU.move dst src
    MU.clear src
    MU.read dst ix

writeGrowRead :: forall a. (Eq a, MU.Unbox a, Arbitrary a, Show a) => Proxy a -> Property
writeGrowRead :: forall a.
(Eq a, Unbox a, Arbitrary a, Show a) =>
Proxy a -> Property
writeGrowRead Proxy a
_ = (a -> NonNegative Int -> Positive Int -> Positive Int -> Property)
-> Property
forall prop. Testable prop => prop -> Property
property ((a -> NonNegative Int -> Positive Int -> Positive Int -> Property)
 -> Property)
-> (a
    -> NonNegative Int -> Positive Int -> Positive Int -> Property)
-> Property
forall a b. (a -> b) -> a -> b
$ \(a
a :: a) (NonNegative Int
ix) (Positive Int
excess) (Positive Int
by) -> do
  (a -> a -> Property
forall a. (Eq a, Show a) => a -> a -> Property
=== a
a) (a -> Property) -> a -> Property
forall a b. (a -> b) -> a -> b
$ (forall s. ST s a) -> a
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s a) -> a) -> (forall s. ST s a) -> a
forall a b. (a -> b) -> a -> b
$ do
    src <- Int -> ST s (MVector (PrimState (ST s)) a)
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
Int -> m (MVector (PrimState m) a)
MU.new (Int
ix Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
excess)
    MU.write src ix a
    dst <- MU.grow src by
    MU.clear src
    MU.read dst ix

slicedWriteCopyRead :: forall a. (Eq a, MU.Unbox a, Arbitrary a, Show a) => Proxy a -> Property
slicedWriteCopyRead :: forall a.
(Eq a, Unbox a, Arbitrary a, Show a) =>
Proxy a -> Property
slicedWriteCopyRead Proxy a
_ = (a
 -> NonNegative Int
 -> Positive Int
 -> NonNegative Int
 -> NonNegative Int
 -> NonNegative Int
 -> NonNegative Int
 -> Property)
-> Property
forall prop. Testable prop => prop -> Property
property ((a
  -> NonNegative Int
  -> Positive Int
  -> NonNegative Int
  -> NonNegative Int
  -> NonNegative Int
  -> NonNegative Int
  -> Property)
 -> Property)
-> (a
    -> NonNegative Int
    -> Positive Int
    -> NonNegative Int
    -> NonNegative Int
    -> NonNegative Int
    -> NonNegative Int
    -> Property)
-> Property
forall a b. (a -> b) -> a -> b
$ \(a
a :: a) (NonNegative Int
ix) (Positive Int
excess) NonNegative Int
beforeSrc NonNegative Int
afterSrc NonNegative Int
beforeDst NonNegative Int
afterDst -> do
  (a -> a -> Property
forall a. (Eq a, Show a) => a -> a -> Property
=== a
a) (a -> Property) -> a -> Property
forall a b. (a -> b) -> a -> b
$ (forall s. ST s a) -> a
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s a) -> a) -> (forall s. ST s a) -> a
forall a b. (a -> b) -> a -> b
$ do
    src <- NonNegative Int -> NonNegative Int -> Int -> ST s (MVector s a)
forall a s.
Unbox a =>
NonNegative Int -> NonNegative Int -> Int -> ST s (MVector s a)
newSlice NonNegative Int
beforeSrc NonNegative Int
afterSrc (Int
ix Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
excess)
    MU.write src ix a
    dst <- newSlice beforeDst afterDst (ix + excess)
    MU.copy dst src
    MU.clear src
    MU.read dst ix

slicedWriteMoveRead :: forall a. (Eq a, MU.Unbox a, Arbitrary a, Show a) => Proxy a -> Property
slicedWriteMoveRead :: forall a.
(Eq a, Unbox a, Arbitrary a, Show a) =>
Proxy a -> Property
slicedWriteMoveRead Proxy a
_ = (a
 -> NonNegative Int
 -> Positive Int
 -> NonNegative Int
 -> NonNegative Int
 -> NonNegative Int
 -> NonNegative Int
 -> Property)
-> Property
forall prop. Testable prop => prop -> Property
property ((a
  -> NonNegative Int
  -> Positive Int
  -> NonNegative Int
  -> NonNegative Int
  -> NonNegative Int
  -> NonNegative Int
  -> Property)
 -> Property)
-> (a
    -> NonNegative Int
    -> Positive Int
    -> NonNegative Int
    -> NonNegative Int
    -> NonNegative Int
    -> NonNegative Int
    -> Property)
-> Property
forall a b. (a -> b) -> a -> b
$ \(a
a :: a) (NonNegative Int
ix) (Positive Int
excess) NonNegative Int
beforeSrc NonNegative Int
afterSrc NonNegative Int
beforeDst NonNegative Int
afterDst -> do
  (a -> a -> Property
forall a. (Eq a, Show a) => a -> a -> Property
=== a
a) (a -> Property) -> a -> Property
forall a b. (a -> b) -> a -> b
$ (forall s. ST s a) -> a
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s a) -> a) -> (forall s. ST s a) -> a
forall a b. (a -> b) -> a -> b
$ do
    src <- NonNegative Int -> NonNegative Int -> Int -> ST s (MVector s a)
forall a s.
Unbox a =>
NonNegative Int -> NonNegative Int -> Int -> ST s (MVector s a)
newSlice NonNegative Int
beforeSrc NonNegative Int
afterSrc (Int
ix Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
excess)
    MU.write src ix a
    dst <- newSlice beforeDst afterDst (ix + excess)
    MU.move dst src
    MU.clear src
    MU.read dst ix

slicedWriteGrowRead :: forall a. (Eq a, MU.Unbox a, Arbitrary a, Show a) => Proxy a -> Property
slicedWriteGrowRead :: forall a.
(Eq a, Unbox a, Arbitrary a, Show a) =>
Proxy a -> Property
slicedWriteGrowRead Proxy a
_ = (a
 -> NonNegative Int
 -> Positive Int
 -> Positive Int
 -> NonNegative Int
 -> NonNegative Int
 -> Property)
-> Property
forall prop. Testable prop => prop -> Property
property ((a
  -> NonNegative Int
  -> Positive Int
  -> Positive Int
  -> NonNegative Int
  -> NonNegative Int
  -> Property)
 -> Property)
-> (a
    -> NonNegative Int
    -> Positive Int
    -> Positive Int
    -> NonNegative Int
    -> NonNegative Int
    -> Property)
-> Property
forall a b. (a -> b) -> a -> b
$ \(a
a :: a) (NonNegative Int
ix) (Positive Int
excess) (Positive Int
by) NonNegative Int
beforeSrc NonNegative Int
afterSrc -> do
  (a -> a -> Property
forall a. (Eq a, Show a) => a -> a -> Property
=== a
a) (a -> Property) -> a -> Property
forall a b. (a -> b) -> a -> b
$ (forall s. ST s a) -> a
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s a) -> a) -> (forall s. ST s a) -> a
forall a b. (a -> b) -> a -> b
$ do
    src <- NonNegative Int -> NonNegative Int -> Int -> ST s (MVector s a)
forall a s.
Unbox a =>
NonNegative Int -> NonNegative Int -> Int -> ST s (MVector s a)
newSlice NonNegative Int
beforeSrc NonNegative Int
afterSrc (Int
ix Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
excess)
    MU.write src ix a
    dst <- MU.grow src by
    MU.clear src
    MU.read dst ix

-------------------------------------------------------------------------------
-- Write + overwrite around

writeInitializeAroundRead :: forall a. (Eq a, MU.Unbox a, Arbitrary a, Show a) => Proxy a -> Property
writeInitializeAroundRead :: forall a.
(Eq a, Unbox a, Arbitrary a, Show a) =>
Proxy a -> Property
writeInitializeAroundRead Proxy a
_ = (a -> NonNegative Int -> Positive Int -> Property) -> Property
forall prop. Testable prop => prop -> Property
property ((a -> NonNegative Int -> Positive Int -> Property) -> Property)
-> (a -> NonNegative Int -> Positive Int -> Property) -> Property
forall a b. (a -> b) -> a -> b
$ \(a
a :: a) (NonNegative Int
ix) (Positive Int
excess) -> do
  (a -> a -> Property
forall a. (Eq a, Show a) => a -> a -> Property
=== a
a) (a -> Property) -> a -> Property
forall a b. (a -> b) -> a -> b
$ (forall s. ST s a) -> a
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s a) -> a) -> (forall s. ST s a) -> a
forall a b. (a -> b) -> a -> b
$ do
    arr <- Int -> ST s (MVector (PrimState (ST s)) a)
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
Int -> m (MVector (PrimState m) a)
MU.new (Int
ix Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
excess)
    MU.write arr ix a
    when (ix > 0) $
      MU.basicInitialize (MU.slice 0 ix arr)
    when (excess > 1) $
      MU.basicInitialize (MU.slice (ix + 1) (excess - 1) arr)
    MU.read arr ix

writeClearAroundRead :: forall a. (Eq a, MU.Unbox a, Arbitrary a, Show a) => Proxy a -> Property
writeClearAroundRead :: forall a.
(Eq a, Unbox a, Arbitrary a, Show a) =>
Proxy a -> Property
writeClearAroundRead Proxy a
_ = (a -> NonNegative Int -> Positive Int -> Property) -> Property
forall prop. Testable prop => prop -> Property
property ((a -> NonNegative Int -> Positive Int -> Property) -> Property)
-> (a -> NonNegative Int -> Positive Int -> Property) -> Property
forall a b. (a -> b) -> a -> b
$ \(a
a :: a) (NonNegative Int
ix) (Positive Int
excess) -> do
  (a -> a -> Property
forall a. (Eq a, Show a) => a -> a -> Property
=== a
a) (a -> Property) -> a -> Property
forall a b. (a -> b) -> a -> b
$ (forall s. ST s a) -> a
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s a) -> a) -> (forall s. ST s a) -> a
forall a b. (a -> b) -> a -> b
$ do
    arr <- Int -> ST s (MVector (PrimState (ST s)) a)
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
Int -> m (MVector (PrimState m) a)
MU.new (Int
ix Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
excess)
    MU.write arr ix a
    when (ix > 0) $
      MU.clear (MU.slice 0 ix arr)
    when (excess > 1) $
      MU.clear (MU.slice (ix + 1) (excess - 1) arr)
    MU.read arr ix

writeSetAroundRead :: forall a. (Eq a, MU.Unbox a, Arbitrary a, Show a) => Proxy a -> Property
writeSetAroundRead :: forall a.
(Eq a, Unbox a, Arbitrary a, Show a) =>
Proxy a -> Property
writeSetAroundRead Proxy a
_ = (a -> a -> NonNegative Int -> Positive Int -> Property) -> Property
forall prop. Testable prop => prop -> Property
property ((a -> a -> NonNegative Int -> Positive Int -> Property)
 -> Property)
-> (a -> a -> NonNegative Int -> Positive Int -> Property)
-> Property
forall a b. (a -> b) -> a -> b
$ \(a
a :: a) (a
b :: a) (NonNegative Int
ix) (Positive Int
excess) -> do
  (a -> a -> Property
forall a. (Eq a, Show a) => a -> a -> Property
=== a
a) (a -> Property) -> a -> Property
forall a b. (a -> b) -> a -> b
$ (forall s. ST s a) -> a
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s a) -> a) -> (forall s. ST s a) -> a
forall a b. (a -> b) -> a -> b
$ do
    arr <- Int -> ST s (MVector (PrimState (ST s)) a)
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
Int -> m (MVector (PrimState m) a)
MU.new (Int
ix Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
excess)
    MU.write arr ix a
    when (ix > 0) $
      MU.set (MU.slice 0 ix arr) b
    when (excess > 1) $
      MU.set (MU.slice (ix + 1) (excess - 1) arr) b
    MU.read arr ix

writeWriteAroundRead :: forall a. (Eq a, MU.Unbox a, Arbitrary a, Show a) => Proxy a -> Property
writeWriteAroundRead :: forall a.
(Eq a, Unbox a, Arbitrary a, Show a) =>
Proxy a -> Property
writeWriteAroundRead Proxy a
_ = (a -> a -> NonNegative Int -> Positive Int -> Property) -> Property
forall prop. Testable prop => prop -> Property
property ((a -> a -> NonNegative Int -> Positive Int -> Property)
 -> Property)
-> (a -> a -> NonNegative Int -> Positive Int -> Property)
-> Property
forall a b. (a -> b) -> a -> b
$ \(a
a :: a) (a
b :: a) (NonNegative Int
ix) (Positive Int
excess) -> do
  (a -> a -> Property
forall a. (Eq a, Show a) => a -> a -> Property
=== a
a) (a -> Property) -> a -> Property
forall a b. (a -> b) -> a -> b
$ (forall s. ST s a) -> a
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s a) -> a) -> (forall s. ST s a) -> a
forall a b. (a -> b) -> a -> b
$ do
    arr <- Int -> ST s (MVector (PrimState (ST s)) a)
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
Int -> m (MVector (PrimState m) a)
MU.new (Int
ix Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
excess)
    MU.write arr ix a
    when (ix > 0) $
      MU.write arr (ix - 1) b
    when (excess > 1) $
      MU.write arr (ix + 1) b
    MU.read arr ix

writeCopyAroundRead :: forall a. (Eq a, MU.Unbox a, Arbitrary a, Show a) => Proxy a -> Property
writeCopyAroundRead :: forall a.
(Eq a, Unbox a, Arbitrary a, Show a) =>
Proxy a -> Property
writeCopyAroundRead Proxy a
_ = (a -> NonNegative Int -> Positive Int -> Property) -> Property
forall prop. Testable prop => prop -> Property
property ((a -> NonNegative Int -> Positive Int -> Property) -> Property)
-> (a -> NonNegative Int -> Positive Int -> Property) -> Property
forall a b. (a -> b) -> a -> b
$ \(a
a :: a) (NonNegative Int
ix) (Positive Int
excess) -> do
  (a -> a -> Property
forall a. (Eq a, Show a) => a -> a -> Property
=== a
a) (a -> Property) -> a -> Property
forall a b. (a -> b) -> a -> b
$ (forall s. ST s a) -> a
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s a) -> a) -> (forall s. ST s a) -> a
forall a b. (a -> b) -> a -> b
$ do
    src <- Int -> ST s (MVector (PrimState (ST s)) a)
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
Int -> m (MVector (PrimState m) a)
MU.new (Int
ix Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
excess)
    dst <- MU.new (ix + excess)
    MU.write dst ix a
    when (ix > 0) $
      MU.copy (MU.slice 0 ix dst) (MU.slice 0 ix src)
    when (excess > 1) $
      MU.copy (MU.slice (ix + 1) (excess - 1) dst) (MU.slice (ix + 1) (excess - 1) src)
    MU.read dst ix

writeMoveAroundRead :: forall a. (Eq a, MU.Unbox a, Arbitrary a, Show a) => Proxy a -> Property
writeMoveAroundRead :: forall a.
(Eq a, Unbox a, Arbitrary a, Show a) =>
Proxy a -> Property
writeMoveAroundRead Proxy a
_ = (a -> NonNegative Int -> Positive Int -> Property) -> Property
forall prop. Testable prop => prop -> Property
property ((a -> NonNegative Int -> Positive Int -> Property) -> Property)
-> (a -> NonNegative Int -> Positive Int -> Property) -> Property
forall a b. (a -> b) -> a -> b
$ \(a
a :: a) (NonNegative Int
ix) (Positive Int
excess) -> do
  (a -> a -> Property
forall a. (Eq a, Show a) => a -> a -> Property
=== a
a) (a -> Property) -> a -> Property
forall a b. (a -> b) -> a -> b
$ (forall s. ST s a) -> a
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s a) -> a) -> (forall s. ST s a) -> a
forall a b. (a -> b) -> a -> b
$ do
    src <- Int -> ST s (MVector (PrimState (ST s)) a)
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
Int -> m (MVector (PrimState m) a)
MU.new (Int
ix Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
excess)
    dst <- MU.new (ix + excess)
    MU.write dst ix a
    when (ix > 0) $
      MU.move (MU.slice 0 ix dst) (MU.slice 0 ix src)
    when (excess > 1) $
      MU.move (MU.slice (ix + 1) (excess - 1) dst) (MU.slice (ix + 1) (excess - 1) src)
    MU.read dst ix

-------------------------------------------------------------------------------
-- Two writes + overwrite in between

writeInitializeBetweenRead :: forall a. (Eq a, MU.Unbox a, Arbitrary a, Show a) => Proxy a -> Property
writeInitializeBetweenRead :: forall a.
(Eq a, Unbox a, Arbitrary a, Show a) =>
Proxy a -> Property
writeInitializeBetweenRead Proxy a
_ = (a
 -> a
 -> NonNegative Int
 -> Positive Int
 -> Positive Int
 -> Property)
-> Property
forall prop. Testable prop => prop -> Property
property ((a
  -> a
  -> NonNegative Int
  -> Positive Int
  -> Positive Int
  -> Property)
 -> Property)
-> (a
    -> a
    -> NonNegative Int
    -> Positive Int
    -> Positive Int
    -> Property)
-> Property
forall a b. (a -> b) -> a -> b
$ \(a
a :: a) (a
b :: a) (NonNegative Int
ix) (Positive Int
dix) (Positive Int
excess) -> do
  ((a, a) -> (a, a) -> Property
forall a. (Eq a, Show a) => a -> a -> Property
=== (a
a, a
b)) ((a, a) -> Property) -> (a, a) -> Property
forall a b. (a -> b) -> a -> b
$ (forall s. ST s (a, a)) -> (a, a)
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s (a, a)) -> (a, a))
-> (forall s. ST s (a, a)) -> (a, a)
forall a b. (a -> b) -> a -> b
$ do
    arr <- Int -> ST s (MVector (PrimState (ST s)) a)
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
Int -> m (MVector (PrimState m) a)
MU.new (Int
ix Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
dix Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
excess)
    MU.write arr ix a
    MU.write arr (ix + dix) b
    MU.basicInitialize (MU.slice (ix + 1) (dix - 1) arr)
    (,) <$> MU.read arr ix <*> MU.read arr (ix + dix)

writeClearBetweenRead :: forall a. (Eq a, MU.Unbox a, Arbitrary a, Show a) => Proxy a -> Property
writeClearBetweenRead :: forall a.
(Eq a, Unbox a, Arbitrary a, Show a) =>
Proxy a -> Property
writeClearBetweenRead Proxy a
_ = (a
 -> a
 -> NonNegative Int
 -> Positive Int
 -> Positive Int
 -> Property)
-> Property
forall prop. Testable prop => prop -> Property
property ((a
  -> a
  -> NonNegative Int
  -> Positive Int
  -> Positive Int
  -> Property)
 -> Property)
-> (a
    -> a
    -> NonNegative Int
    -> Positive Int
    -> Positive Int
    -> Property)
-> Property
forall a b. (a -> b) -> a -> b
$ \(a
a :: a) (a
b :: a) (NonNegative Int
ix) (Positive Int
dix) (Positive Int
excess) -> do
  ((a, a) -> (a, a) -> Property
forall a. (Eq a, Show a) => a -> a -> Property
=== (a
a, a
b)) ((a, a) -> Property) -> (a, a) -> Property
forall a b. (a -> b) -> a -> b
$ (forall s. ST s (a, a)) -> (a, a)
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s (a, a)) -> (a, a))
-> (forall s. ST s (a, a)) -> (a, a)
forall a b. (a -> b) -> a -> b
$ do
    arr <- Int -> ST s (MVector (PrimState (ST s)) a)
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
Int -> m (MVector (PrimState m) a)
MU.new (Int
ix Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
dix Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
excess)
    MU.write arr ix a
    MU.write arr (ix + dix) b
    MU.clear (MU.slice (ix + 1) (dix - 1) arr)
    (,) <$> MU.read arr ix <*> MU.read arr (ix + dix)

writeSetBetweenRead :: forall a. (Eq a, MU.Unbox a, Arbitrary a, Show a) => Proxy a -> Property
writeSetBetweenRead :: forall a.
(Eq a, Unbox a, Arbitrary a, Show a) =>
Proxy a -> Property
writeSetBetweenRead Proxy a
_ = (a
 -> a
 -> a
 -> NonNegative Int
 -> Positive Int
 -> Positive Int
 -> Property)
-> Property
forall prop. Testable prop => prop -> Property
property ((a
  -> a
  -> a
  -> NonNegative Int
  -> Positive Int
  -> Positive Int
  -> Property)
 -> Property)
-> (a
    -> a
    -> a
    -> NonNegative Int
    -> Positive Int
    -> Positive Int
    -> Property)
-> Property
forall a b. (a -> b) -> a -> b
$ \(a
a :: a) (a
b :: a) (a
c :: a) (NonNegative Int
ix) (Positive Int
dix) (Positive Int
excess) -> do
  ((a, a) -> (a, a) -> Property
forall a. (Eq a, Show a) => a -> a -> Property
=== (a
a, a
b)) ((a, a) -> Property) -> (a, a) -> Property
forall a b. (a -> b) -> a -> b
$ (forall s. ST s (a, a)) -> (a, a)
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s (a, a)) -> (a, a))
-> (forall s. ST s (a, a)) -> (a, a)
forall a b. (a -> b) -> a -> b
$ do
    arr <- Int -> ST s (MVector (PrimState (ST s)) a)
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
Int -> m (MVector (PrimState m) a)
MU.new (Int
ix Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
dix Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
excess)
    MU.write arr ix a
    MU.write arr (ix + dix) b
    MU.set (MU.slice (ix + 1) (dix - 1) arr) c
    (,) <$> MU.read arr ix <*> MU.read arr (ix + dix)

writeCopyBetweenRead :: forall a. (Eq a, MU.Unbox a, Arbitrary a, Show a) => Proxy a -> Property
writeCopyBetweenRead :: forall a.
(Eq a, Unbox a, Arbitrary a, Show a) =>
Proxy a -> Property
writeCopyBetweenRead Proxy a
_ = (a
 -> a
 -> NonNegative Int
 -> Positive Int
 -> Positive Int
 -> Property)
-> Property
forall prop. Testable prop => prop -> Property
property ((a
  -> a
  -> NonNegative Int
  -> Positive Int
  -> Positive Int
  -> Property)
 -> Property)
-> (a
    -> a
    -> NonNegative Int
    -> Positive Int
    -> Positive Int
    -> Property)
-> Property
forall a b. (a -> b) -> a -> b
$ \(a
a :: a) (a
b :: a) (NonNegative Int
ix) (Positive Int
dix) (Positive Int
excess) -> do
  ((a, a) -> (a, a) -> Property
forall a. (Eq a, Show a) => a -> a -> Property
=== (a
a, a
b)) ((a, a) -> Property) -> (a, a) -> Property
forall a b. (a -> b) -> a -> b
$ (forall s. ST s (a, a)) -> (a, a)
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s (a, a)) -> (a, a))
-> (forall s. ST s (a, a)) -> (a, a)
forall a b. (a -> b) -> a -> b
$ do
    src <- Int -> ST s (MVector (PrimState (ST s)) a)
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
Int -> m (MVector (PrimState m) a)
MU.new (Int
ix Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
dix Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
excess)
    dst <- MU.new (ix + dix + excess)
    MU.write dst ix a
    MU.write dst (ix + dix) b
    MU.copy (MU.slice (ix + 1) (dix - 1) dst) (MU.slice (ix + 1) (dix - 1) src)
    (,) <$> MU.read dst ix <*> MU.read dst (ix + dix)

writeMoveBetweenRead :: forall a. (Eq a, MU.Unbox a, Arbitrary a, Show a) => Proxy a -> Property
writeMoveBetweenRead :: forall a.
(Eq a, Unbox a, Arbitrary a, Show a) =>
Proxy a -> Property
writeMoveBetweenRead Proxy a
_ = (a
 -> a
 -> NonNegative Int
 -> Positive Int
 -> Positive Int
 -> Property)
-> Property
forall prop. Testable prop => prop -> Property
property ((a
  -> a
  -> NonNegative Int
  -> Positive Int
  -> Positive Int
  -> Property)
 -> Property)
-> (a
    -> a
    -> NonNegative Int
    -> Positive Int
    -> Positive Int
    -> Property)
-> Property
forall a b. (a -> b) -> a -> b
$ \(a
a :: a) (a
b :: a) (NonNegative Int
ix) (Positive Int
dix) (Positive Int
excess) -> do
  ((a, a) -> (a, a) -> Property
forall a. (Eq a, Show a) => a -> a -> Property
=== (a
a, a
b)) ((a, a) -> Property) -> (a, a) -> Property
forall a b. (a -> b) -> a -> b
$ (forall s. ST s (a, a)) -> (a, a)
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s (a, a)) -> (a, a))
-> (forall s. ST s (a, a)) -> (a, a)
forall a b. (a -> b) -> a -> b
$ do
    src <- Int -> ST s (MVector (PrimState (ST s)) a)
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
Int -> m (MVector (PrimState m) a)
MU.new (Int
ix Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
dix Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
excess)
    dst <- MU.new (ix + dix + excess)
    MU.write dst ix a
    MU.write dst (ix + dix) b
    MU.move (MU.slice (ix + 1) (dix - 1) dst) (MU.slice (ix + 1) (dix - 1) src)
    (,) <$> MU.read dst ix <*> MU.read dst (ix + dix)

-------------------------------------------------------------------------------
-- Utils

newSlice :: MU.Unbox a => NonNegative Int -> NonNegative Int -> Int -> ST s (MU.MVector s a)
newSlice :: forall a s.
Unbox a =>
NonNegative Int -> NonNegative Int -> Int -> ST s (MVector s a)
newSlice (NonNegative Int
before) (NonNegative Int
after) Int
len = do
  arr <- Int -> ST s (MVector (PrimState (ST s)) a)
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
Int -> m (MVector (PrimState m) a)
MU.new (Int
before Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
len Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
after)
  pure $ MU.slice before len arr

#endif