    -- |
    -- 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