{-# LANGUAGE CPP              #-}
{-# LANGUAGE DataKinds        #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE RankNTypes       #-}
{-# LANGUAGE TypeOperators    #-}

{-|
This module re-exports the functionality in 'Data.Vector.Generic.Mutable.Sized'
 specialized to 'Data.Vector.Storable.Mutable'.

Functions returning a vector determine the size from the type context unless
they have a @'@ suffix in which case they take an explicit 'Proxy' argument.

Functions where the resulting vector size is not known until runtime are
not exported.
-}

module Data.Vector.Storable.Mutable.Sized
 ( MVector
   -- * Accessors
   -- ** Length information
  , length
  , length'
  , null
   -- ** Extracting subvectors
  , slice
  , slice'
  , init
  , tail
  , take
  , take'
  , drop
  , drop'
  , splitAt
  , splitAt'
  -- ** Overlaps
  , overlaps
  -- * Construction
  -- ** Initialisation
  , new
  , unsafeNew
  , replicate
  , replicate'
  , replicateM
  , replicateM'
  , clone
  -- ** Growing
  , grow
  , growFront
  -- ** Restricting memory usage
  , clear
  -- * Accessing individual elements
  , read
  , read'
  , write
  , write'
  , modify
  , modify'
  , swap
  , exchange
  , exchange'
  , unsafeRead
  , unsafeWrite
  , unsafeModify
  , unsafeSwap
  , unsafeExchange
#if MIN_VERSION_vector(0,12,0)
  -- * Modifying vectors
  , nextPermutation
#endif
  -- ** Filling and copying
  , set
  , copy
  , move
  , unsafeCopy
    -- * Conversions
    -- ** Unsized Mutable Vectors
  , toSized
  , withSized
  , fromSized
  ) where

import qualified Data.Vector.Generic.Mutable.Sized as VGM
import qualified Data.Vector.Storable.Mutable as VSM
import Foreign.Storable
import GHC.TypeLits
import Data.Finite
import Data.Proxy
import Control.Monad.Primitive
import Prelude hiding ( length, null, replicate, init,
                        tail, take, drop, splitAt, read )


-- | 'Data.Vector.Generic.Mutable.Sized.Vector' specialized to use
-- 'Data.Vector.Storable.Mutable'.
type MVector = VGM.MVector VSM.MVector

-- * Accessors

-- ** Length information

-- | /O(1)/ Yield the length of the mutable vector as an 'Int'.
length :: forall n s a. (KnownNat n)
       => MVector n s a -> Int
length :: MVector n s a -> Int
length = MVector n s a -> Int
forall (v :: * -> * -> *) (n :: Nat) s a.
KnownNat n =>
MVector v n s a -> Int
VGM.length
{-# inline length #-}

-- | /O(1)/ Yield the length of the mutable vector as a 'Proxy'.
length' :: forall n s a. ()
        => MVector n s a -> Proxy n
length' :: MVector n s a -> Proxy n
length' = MVector n s a -> Proxy n
forall (v :: * -> * -> *) (n :: Nat) s a.
MVector v n s a -> Proxy n
VGM.length'
{-# inline length' #-}

-- | /O(1)/ Check whether the mutable vector is empty.
null :: forall n s a. (KnownNat n)
       => MVector n s a -> Bool
null :: MVector n s a -> Bool
null = MVector n s a -> Bool
forall (v :: * -> * -> *) (n :: Nat) s a.
KnownNat n =>
MVector v n s a -> Bool
VGM.null
{-# inline null #-}

-- ** Extracting subvectors

-- | /O(1)/ Yield a slice of the mutable vector without copying it with an
-- inferred length argument.
slice :: forall i n k s a p. (KnownNat i, KnownNat n, Storable a)
      => p i -- ^ starting index
      -> MVector (i+n+k) s a
      -> MVector n s a
slice :: p i -> MVector ((i + n) + k) s a -> MVector n s a
slice = p i -> MVector ((i + n) + k) s a -> MVector n s a
forall (v :: * -> * -> *) (i :: Nat) (n :: Nat) (k :: Nat) s a
       (p :: Nat -> *).
(KnownNat i, KnownNat n, MVector v a) =>
p i -> MVector v ((i + n) + k) s a -> MVector v n s a
VGM.slice
{-# inline slice #-}

-- | /O(1)/ Yield a slice of the mutable vector without copying it with an
-- explicit length argument.
slice' :: forall i n k s a p
        . (KnownNat i, KnownNat n, Storable a)
       => p i -- ^ starting index
       -> p n -- ^ length
       -> MVector (i+n+k) s a
       -> MVector n s a
slice' :: p i -> p n -> MVector ((i + n) + k) s a -> MVector n s a
slice' = p i -> p n -> MVector ((i + n) + k) s a -> MVector n s a
forall (v :: * -> * -> *) (i :: Nat) (n :: Nat) (k :: Nat) s a
       (p :: Nat -> *).
(KnownNat i, KnownNat n, MVector v a) =>
p i -> p n -> MVector v ((i + n) + k) s a -> MVector v n s a
VGM.slice'
{-# inline slice' #-}

-- | /O(1)/ Yield all but the last element of a non-empty mutable vector
-- without copying.
init :: forall n s a. Storable a
     => MVector (n+1) s a -> MVector n s a
init :: MVector (n + 1) s a -> MVector n s a
init = MVector (n + 1) s a -> MVector n s a
forall (v :: * -> * -> *) (n :: Nat) s a.
MVector v a =>
MVector v (n + 1) s a -> MVector v n s a
VGM.init
{-# inline init #-}

-- | /O(1)/ Yield all but the first element of a non-empty mutable vector
-- without copying.
tail :: forall n s a. Storable a
     => MVector (1+n) s a -> MVector n s a
tail :: MVector (1 + n) s a -> MVector n s a
tail = MVector (1 + n) s a -> MVector n s a
forall (v :: * -> * -> *) (n :: Nat) s a.
MVector v a =>
MVector v (1 + n) s a -> MVector v n s a
VGM.tail
{-# inline tail #-}

-- | /O(1)/ Yield the first @n@ elements. The resulting vector always contains
-- this many elements. The length of the resulting vector is inferred from the
-- type.
take :: forall n k s a. (KnownNat n, Storable a)
     => MVector (n+k) s a -> MVector n s a
take :: MVector (n + k) s a -> MVector n s a
take = MVector (n + k) s a -> MVector n s a
forall (v :: * -> * -> *) (n :: Nat) (k :: Nat) s a.
(KnownNat n, MVector v a) =>
MVector v (n + k) s a -> MVector v n s a
VGM.take
{-# inline take #-}

-- | /O(1)/ Yield the first @n@ elements. The resulting vector always contains
-- this many elements. The length of the resulting vector is given explicitly
-- as a 'Proxy' argument.
take' :: forall n k s a p. (KnownNat n, Storable a)
      => p n -> MVector (n+k) s a -> MVector n s a
take' :: p n -> MVector (n + k) s a -> MVector n s a
take' = p n -> MVector (n + k) s a -> MVector n s a
forall (v :: * -> * -> *) (n :: Nat) (k :: Nat) s a
       (p :: Nat -> *).
(KnownNat n, MVector v a) =>
p n -> MVector v (n + k) s a -> MVector v n s a
VGM.take'
{-# inline take' #-}

-- | /O(1)/ Yield all but the the first @n@ elements. The given vector must
-- contain at least this many elements. The length of the resulting vector is
-- inferred from the type.
drop :: forall n k s a. (KnownNat n, Storable a)
     => MVector (n+k) s a -> MVector k s a
drop :: MVector (n + k) s a -> MVector k s a
drop = MVector (n + k) s a -> MVector k s a
forall (v :: * -> * -> *) (n :: Nat) (k :: Nat) s a.
(KnownNat n, MVector v a) =>
MVector v (n + k) s a -> MVector v k s a
VGM.drop
{-# inline drop #-}

-- | /O(1)/ Yield all but the the first @n@ elements. The given vector must
-- contain at least this many elements. The length of the resulting vector is
-- givel explicitly as a 'Proxy' argument.
drop' :: forall n k s a p. (KnownNat n, Storable a)
      => p n -> MVector (n+k) s a -> MVector k s a
drop' :: p n -> MVector (n + k) s a -> MVector k s a
drop' = p n -> MVector (n + k) s a -> MVector k s a
forall (v :: * -> * -> *) (n :: Nat) (k :: Nat) s a
       (p :: Nat -> *).
(KnownNat n, MVector v a) =>
p n -> MVector v (n + k) s a -> MVector v k s a
VGM.drop'
{-# inline drop' #-}

-- | /O(1)/ Yield the first @n@ elements, paired with the rest, without copying.
-- The lengths of the resulting vectors are inferred from the type.
splitAt :: forall n m s a. (KnownNat n, Storable a)
        => MVector (n+m) s a -> (MVector n s a, MVector m s a)
splitAt :: MVector (n + m) s a -> (MVector n s a, MVector m s a)
splitAt = MVector (n + m) s a -> (MVector n s a, MVector m s a)
forall (v :: * -> * -> *) (n :: Nat) (m :: Nat) s a.
(KnownNat n, MVector v a) =>
MVector v (n + m) s a -> (MVector v n s a, MVector v m s a)
VGM.splitAt
{-# inline splitAt #-}

-- | /O(1)/ Yield the first @n@ elements, paired with the rest, without
-- copying.  The length of the first resulting vector is passed explicitly as a
-- 'Proxy' argument.
splitAt' :: forall n m s a p. (KnownNat n, Storable a)
         => p n -> MVector (n+m) s a -> (MVector n s a, MVector m s a)
splitAt' :: p n -> MVector (n + m) s a -> (MVector n s a, MVector m s a)
splitAt' = p n -> MVector (n + m) s a -> (MVector n s a, MVector m s a)
forall (v :: * -> * -> *) (n :: Nat) (m :: Nat) s a
       (p :: Nat -> *).
(KnownNat n, MVector v a) =>
p n -> MVector v (n + m) s a -> (MVector v n s a, MVector v m s a)
VGM.splitAt'
{-# inline splitAt' #-}

-- ** Overlaps

-- | /O(1)/ Check if two vectors overlap. 
overlaps :: forall n k s a. Storable a
         => MVector n s a
         -> MVector k s a
         -> Bool
overlaps :: MVector n s a -> MVector k s a -> Bool
overlaps = MVector n s a -> MVector k s a -> Bool
forall (v :: * -> * -> *) (n :: Nat) (k :: Nat) s a.
MVector v a =>
MVector v n s a -> MVector v k s a -> Bool
VGM.overlaps
{-# inline overlaps #-}

-- * Construction

-- ** Initialisation

-- | Create a mutable vector where the length is inferred from the type.
new :: forall n m a. (KnownNat n, PrimMonad m, Storable a)
    => m (MVector n (PrimState m) a)
new :: m (MVector n (PrimState m) a)
new = m (MVector n (PrimState m) a)
forall (v :: * -> * -> *) (n :: Nat) (m :: * -> *) a.
(KnownNat n, PrimMonad m, MVector v a) =>
m (MVector v n (PrimState m) a)
VGM.new
{-# inline new #-}

-- | Create a mutable vector where the length is inferred from the type.
-- The memory is not initialized.
unsafeNew :: forall n m a. (KnownNat n, PrimMonad m, Storable a)
          => m (MVector n (PrimState m) a)
unsafeNew :: m (MVector n (PrimState m) a)
unsafeNew = m (MVector n (PrimState m) a)
forall (v :: * -> * -> *) (n :: Nat) (m :: * -> *) a.
(KnownNat n, PrimMonad m, MVector v a) =>
m (MVector v n (PrimState m) a)
VGM.unsafeNew
{-# inline unsafeNew #-}

-- | Create a mutable vector where the length is inferred from the type and
-- fill it with an initial value.
replicate :: forall n m a. (KnownNat n, PrimMonad m, Storable a)
          => a -> m (MVector n (PrimState m) a)
replicate :: a -> m (MVector n (PrimState m) a)
replicate = a -> m (MVector n (PrimState m) a)
forall (v :: * -> * -> *) (n :: Nat) (m :: * -> *) a.
(KnownNat n, PrimMonad m, MVector v a) =>
a -> m (MVector v n (PrimState m) a)
VGM.replicate
{-# inline replicate #-}

-- | Create a mutable vector where the length is given explicitly as
-- a 'Proxy' argument and fill it with an initial value.
replicate' :: forall n m a p. (KnownNat n, PrimMonad m, Storable a)
           => p n -> a -> m (MVector n (PrimState m) a)
replicate' :: p n -> a -> m (MVector n (PrimState m) a)
replicate' = p n -> a -> m (MVector n (PrimState m) a)
forall (v :: * -> * -> *) (n :: Nat) (m :: * -> *) a
       (p :: Nat -> *).
(KnownNat n, PrimMonad m, MVector v a) =>
p n -> a -> m (MVector v n (PrimState m) a)
VGM.replicate'
{-# inline replicate' #-}

-- | Create a mutable vector where the length is inferred from the type and
-- fill it with values produced by repeatedly executing the monadic action.
replicateM :: forall n m a. (KnownNat n, PrimMonad m, Storable a)
           => m a -> m (MVector n (PrimState m) a)
replicateM :: m a -> m (MVector n (PrimState m) a)
replicateM = m a -> m (MVector n (PrimState m) a)
forall (v :: * -> * -> *) (n :: Nat) (m :: * -> *) a.
(KnownNat n, PrimMonad m, MVector v a) =>
m a -> m (MVector v n (PrimState m) a)
VGM.replicateM
{-# inline replicateM #-}

-- | Create a mutable vector where the length is given explicitly as
-- a 'Proxy' argument and fill it with values produced by repeatedly
-- executing the monadic action.
replicateM' :: forall n m a p. (KnownNat n, PrimMonad m, Storable a)
           => p n -> m a -> m (MVector n (PrimState m) a)
replicateM' :: p n -> m a -> m (MVector n (PrimState m) a)
replicateM' = p n -> m a -> m (MVector n (PrimState m) a)
forall (v :: * -> * -> *) (n :: Nat) (m :: * -> *) a
       (p :: Nat -> *).
(KnownNat n, PrimMonad m, MVector v a) =>
p n -> m a -> m (MVector v n (PrimState m) a)
VGM.replicateM'
{-# inline replicateM' #-}

-- | Create a copy of a mutable vector.
clone :: forall n m a. (PrimMonad m, Storable a)
      => MVector n (PrimState m) a -> m (MVector n (PrimState m) a)
clone :: MVector n (PrimState m) a -> m (MVector n (PrimState m) a)
clone = MVector n (PrimState m) a -> m (MVector n (PrimState m) a)
forall (v :: * -> * -> *) (n :: Nat) (m :: * -> *) a.
(PrimMonad m, MVector v a) =>
MVector v n (PrimState m) a -> m (MVector v n (PrimState m) a)
VGM.clone
{-# inline clone #-}

-- ** Growing

-- | Grow a mutable vector by an amount given explicitly as a 'Proxy'
-- argument.
grow :: forall n k m a p. (KnownNat k, PrimMonad m, Storable a)
      => p k -> MVector n (PrimState m) a -> m (MVector (n + k) (PrimState m) a)
grow :: p k
-> MVector n (PrimState m) a -> m (MVector (n + k) (PrimState m) a)
grow = p k
-> MVector n (PrimState m) a -> m (MVector (n + k) (PrimState m) a)
forall (v :: * -> * -> *) (n :: Nat) (k :: Nat) (m :: * -> *) a
       (p :: Nat -> *).
(KnownNat k, PrimMonad m, MVector v a) =>
p k
-> MVector v n (PrimState m) a
-> m (MVector v (n + k) (PrimState m) a)
VGM.grow
{-# inline grow #-}

-- | Grow a mutable vector (from the front) by an amount given explicitly
-- as a 'Proxy' argument.
growFront :: forall n k m a p. (KnownNat k, PrimMonad m, Storable a)
      => p k -> MVector n (PrimState m) a -> m (MVector (n + k) (PrimState m) a)
growFront :: p k
-> MVector n (PrimState m) a -> m (MVector (n + k) (PrimState m) a)
growFront = p k
-> MVector n (PrimState m) a -> m (MVector (n + k) (PrimState m) a)
forall (v :: * -> * -> *) (n :: Nat) (k :: Nat) (m :: * -> *) a
       (p :: Nat -> *).
(KnownNat k, PrimMonad m, MVector v a) =>
p k
-> MVector v n (PrimState m) a
-> m (MVector v (n + k) (PrimState m) a)
VGM.growFront
{-# inline growFront #-}

-- ** Restricting memory usage

-- | Reset all elements of the vector to some undefined value, clearing all
-- references to external objects.
clear :: (PrimMonad m, Storable a) => MVector n (PrimState m) a -> m ()
clear :: MVector n (PrimState m) a -> m ()
clear = MVector n (PrimState m) a -> m ()
forall (m :: * -> *) (v :: * -> * -> *) a (n :: Nat).
(PrimMonad m, MVector v a) =>
MVector v n (PrimState m) a -> m ()
VGM.clear
{-# inline clear #-}

-- * Accessing individual elements

-- | /O(1)/ Yield the element at a given type-safe position using 'Finite'.
read :: forall n m a. (PrimMonad m, Storable a)
      => MVector n (PrimState m) a -> Finite n -> m a
read :: MVector n (PrimState m) a -> Finite n -> m a
read = MVector n (PrimState m) a -> Finite n -> m a
forall (v :: * -> * -> *) (n :: Nat) (m :: * -> *) a.
(PrimMonad m, MVector v a) =>
MVector v n (PrimState m) a -> Finite n -> m a
VGM.read
{-# inline read #-}

-- | /O(1)/ Yield the element at a given type-safe position using 'Proxy'.
read' :: forall n k a m p. (KnownNat k, PrimMonad m, Storable a)
       => MVector (n+k+1) (PrimState m) a -> p k -> m a
read' :: MVector ((n + k) + 1) (PrimState m) a -> p k -> m a
read' = MVector ((n + k) + 1) (PrimState m) a -> p k -> m a
forall (v :: * -> * -> *) (n :: Nat) (k :: Nat) a (m :: * -> *)
       (p :: Nat -> *).
(KnownNat k, PrimMonad m, MVector v a) =>
MVector v ((n + k) + 1) (PrimState m) a -> p k -> m a
VGM.read'
{-# inline read' #-}

-- | /O(1)/ Yield the element at a given 'Int' position without bounds
-- checking.
unsafeRead :: forall n a m. (PrimMonad m, Storable a)
           => MVector n (PrimState m) a -> Int -> m a
unsafeRead :: MVector n (PrimState m) a -> Int -> m a
unsafeRead = MVector n (PrimState m) a -> Int -> m a
forall (v :: * -> * -> *) (n :: Nat) a (m :: * -> *).
(PrimMonad m, MVector v a) =>
MVector v n (PrimState m) a -> Int -> m a
VGM.unsafeRead
{-# inline unsafeRead #-}

-- | /O(1)/ Replace the element at a given type-safe position using 'Finite'.
write :: forall n m a. (PrimMonad m, Storable a)
      => MVector n (PrimState m) a -> Finite n -> a -> m ()
write :: MVector n (PrimState m) a -> Finite n -> a -> m ()
write = MVector n (PrimState m) a -> Finite n -> a -> m ()
forall (v :: * -> * -> *) (n :: Nat) (m :: * -> *) a.
(PrimMonad m, MVector v a) =>
MVector v n (PrimState m) a -> Finite n -> a -> m ()
VGM.write
{-# inline write #-}

-- | /O(1)/ Replace the element at a given type-safe position using 'Proxy'.
write' :: forall n k a m p. (KnownNat k, PrimMonad m, Storable a)
       => MVector (n+k+1) (PrimState m) a -> p k -> a -> m ()
write' :: MVector ((n + k) + 1) (PrimState m) a -> p k -> a -> m ()
write' = MVector ((n + k) + 1) (PrimState m) a -> p k -> a -> m ()
forall (v :: * -> * -> *) (n :: Nat) (k :: Nat) a (m :: * -> *)
       (p :: Nat -> *).
(KnownNat k, PrimMonad m, MVector v a) =>
MVector v ((n + k) + 1) (PrimState m) a -> p k -> a -> m ()
VGM.write'
{-# inline write' #-}

-- | /O(1)/ Replace the element at a given 'Int' position without bounds
-- checking.
unsafeWrite :: forall n m a. (PrimMonad m, Storable a)
      => MVector n (PrimState m) a -> Int -> a -> m ()
unsafeWrite :: MVector n (PrimState m) a -> Int -> a -> m ()
unsafeWrite = MVector n (PrimState m) a -> Int -> a -> m ()
forall (v :: * -> * -> *) (n :: Nat) (m :: * -> *) a.
(PrimMonad m, MVector v a) =>
MVector v n (PrimState m) a -> Int -> a -> m ()
VGM.unsafeWrite
{-# inline unsafeWrite #-}

-- | /O(1)/ Modify the element at a given type-safe position using 'Finite'.
modify :: forall n m a. (PrimMonad m, Storable a)
       => MVector n (PrimState m) a -> (a -> a) -> Finite n -> m ()
modify :: MVector n (PrimState m) a -> (a -> a) -> Finite n -> m ()
modify = MVector n (PrimState m) a -> (a -> a) -> Finite n -> m ()
forall (v :: * -> * -> *) (n :: Nat) (m :: * -> *) a.
(PrimMonad m, MVector v a) =>
MVector v n (PrimState m) a -> (a -> a) -> Finite n -> m ()
VGM.modify
{-# inline modify #-}

-- | /O(1)/ Modify the element at a given type-safe position using 'Proxy'.
modify' :: forall n k a m p. (KnownNat k, PrimMonad m, Storable a)
        => MVector (n+k+1) (PrimState m) a -> (a -> a) -> p k -> m ()
modify' :: MVector ((n + k) + 1) (PrimState m) a -> (a -> a) -> p k -> m ()
modify' = MVector ((n + k) + 1) (PrimState m) a -> (a -> a) -> p k -> m ()
forall (v :: * -> * -> *) (n :: Nat) (k :: Nat) a (m :: * -> *)
       (p :: Nat -> *).
(KnownNat k, PrimMonad m, MVector v a) =>
MVector v ((n + k) + 1) (PrimState m) a -> (a -> a) -> p k -> m ()
VGM.modify'
{-# inline modify' #-}

-- | /O(1)/ Modify the element at a given 'Int' position without bounds
-- checking.
unsafeModify :: forall n m a. (PrimMonad m, Storable a)
       => MVector n (PrimState m) a -> (a -> a) -> Int -> m ()
unsafeModify :: MVector n (PrimState m) a -> (a -> a) -> Int -> m ()
unsafeModify = MVector n (PrimState m) a -> (a -> a) -> Int -> m ()
forall (v :: * -> * -> *) (n :: Nat) (m :: * -> *) a.
(PrimMonad m, MVector v a) =>
MVector v n (PrimState m) a -> (a -> a) -> Int -> m ()
VGM.unsafeModify
{-# inline unsafeModify #-}

-- | /O(1)/ Swap the elements at the given type-safe positions using 'Finite's.
swap :: forall n m a. (PrimMonad m, Storable a)
     => MVector n (PrimState m) a -> Finite n -> Finite n -> m ()
swap :: MVector n (PrimState m) a -> Finite n -> Finite n -> m ()
swap = MVector n (PrimState m) a -> Finite n -> Finite n -> m ()
forall (v :: * -> * -> *) (n :: Nat) (m :: * -> *) a.
(PrimMonad m, MVector v a) =>
MVector v n (PrimState m) a -> Finite n -> Finite n -> m ()
VGM.swap
{-# inline swap #-}

-- | /O(1)/ Swap the elements at the given 'Int' positions without bounds
-- checking.
unsafeSwap :: forall n m a. (PrimMonad m, Storable a)
           => MVector n (PrimState m) a -> Int -> Int -> m ()
unsafeSwap :: MVector n (PrimState m) a -> Int -> Int -> m ()
unsafeSwap = MVector n (PrimState m) a -> Int -> Int -> m ()
forall (v :: * -> * -> *) (n :: Nat) (m :: * -> *) a.
(PrimMonad m, MVector v a) =>
MVector v n (PrimState m) a -> Int -> Int -> m ()
VGM.unsafeSwap
{-# inline unsafeSwap #-}

-- | /O(1)/ Replace the element at a given type-safe position and return
-- the old element, using 'Finite'.
exchange :: forall n m a. (PrimMonad m, Storable a)
         => MVector n (PrimState m) a -> Finite n -> a -> m a
exchange :: MVector n (PrimState m) a -> Finite n -> a -> m a
exchange = MVector n (PrimState m) a -> Finite n -> a -> m a
forall (v :: * -> * -> *) (n :: Nat) (m :: * -> *) a.
(PrimMonad m, MVector v a) =>
MVector v n (PrimState m) a -> Finite n -> a -> m a
VGM.exchange
{-# inline exchange #-}

-- | /O(1)/ Replace the element at a given type-safe position and return
-- the old element, using 'Finite'.
exchange' :: forall n k a m p. (KnownNat k, PrimMonad m, Storable a)
          => MVector (n+k+1) (PrimState m) a -> p k -> a -> m a
exchange' :: MVector ((n + k) + 1) (PrimState m) a -> p k -> a -> m a
exchange' = MVector ((n + k) + 1) (PrimState m) a -> p k -> a -> m a
forall (v :: * -> * -> *) (n :: Nat) (k :: Nat) a (m :: * -> *)
       (p :: Nat -> *).
(KnownNat k, PrimMonad m, MVector v a) =>
MVector v ((n + k) + 1) (PrimState m) a -> p k -> a -> m a
VGM.exchange'
{-# inline exchange' #-}

-- | /O(1)/ Replace the element at a given 'Int' position and return
-- the old element. No bounds checks are performed.
unsafeExchange :: forall n m a. (PrimMonad m, Storable a)
         => MVector n (PrimState m) a -> Int -> a -> m a
unsafeExchange :: MVector n (PrimState m) a -> Int -> a -> m a
unsafeExchange = MVector n (PrimState m) a -> Int -> a -> m a
forall (v :: * -> * -> *) (n :: Nat) (m :: * -> *) a.
(PrimMonad m, MVector v a) =>
MVector v n (PrimState m) a -> Int -> a -> m a
VGM.unsafeExchange
{-# inline unsafeExchange #-}

#if MIN_VERSION_vector(0,12,0)
-- * Modifying vectors

-- | Compute the next permutation (lexicographically) of a given vector
-- in-place.  Returns 'False' when the input is the last permutation.
nextPermutation :: forall n e m. (Ord e, PrimMonad m, Storable e)
                => MVector n (PrimState m) e -> m Bool
nextPermutation :: MVector n (PrimState m) e -> m Bool
nextPermutation = MVector n (PrimState m) e -> m Bool
forall (v :: * -> * -> *) (n :: Nat) e (m :: * -> *).
(Ord e, PrimMonad m, MVector v e) =>
MVector v n (PrimState m) e -> m Bool
VGM.nextPermutation
{-# inline nextPermutation #-}
#endif

-- ** Filling and copying

-- | Set all elements of the vector to the given value.
set :: (PrimMonad m, Storable a) => MVector n (PrimState m) a -> a -> m ()
set :: MVector n (PrimState m) a -> a -> m ()
set = MVector n (PrimState m) a -> a -> m ()
forall (m :: * -> *) (v :: * -> * -> *) a (n :: Nat).
(PrimMonad m, MVector v a) =>
MVector v n (PrimState m) a -> a -> m ()
VGM.set
{-# inline set #-}

-- | Copy a vector. The two vectors may not overlap.
copy :: (PrimMonad m, Storable a)
     => MVector n (PrimState m) a       -- ^ target
     -> MVector n (PrimState m) a       -- ^ source
     -> m ()
copy :: MVector n (PrimState m) a -> MVector n (PrimState m) a -> m ()
copy = MVector n (PrimState m) a -> MVector n (PrimState m) a -> m ()
forall (m :: * -> *) (v :: * -> * -> *) a (n :: Nat).
(PrimMonad m, MVector v a) =>
MVector v n (PrimState m) a -> MVector v n (PrimState m) a -> m ()
VGM.copy
{-# inline copy #-}

-- * Conversions

-- ** Unsized Mutable Vectors

-- | Copy a vector. The two vectors may not overlap. This is not checked.
unsafeCopy :: (PrimMonad m, Storable a)
           => MVector n (PrimState m) a       -- ^ target
           -> MVector n (PrimState m) a       -- ^ source
           -> m ()
unsafeCopy :: MVector n (PrimState m) a -> MVector n (PrimState m) a -> m ()
unsafeCopy = MVector n (PrimState m) a -> MVector n (PrimState m) a -> m ()
forall (m :: * -> *) (v :: * -> * -> *) a (n :: Nat).
(PrimMonad m, MVector v a) =>
MVector v n (PrimState m) a -> MVector v n (PrimState m) a -> m ()
VGM.unsafeCopy
{-# inline unsafeCopy #-}

-- | Move the contents of a vector.  If the two vectors do not overlap,
-- this is equivalent to 'copy'.  Otherwise, the copying is performed as if
-- the source vector were copied to a temporary vector and then the
-- temporary vector was copied to the target vector.
move :: (PrimMonad m, Storable a)
     => MVector n (PrimState m) a       -- ^ target
     -> MVector n (PrimState m) a       -- ^ source
     -> m ()
move :: MVector n (PrimState m) a -> MVector n (PrimState m) a -> m ()
move = MVector n (PrimState m) a -> MVector n (PrimState m) a -> m ()
forall (m :: * -> *) (v :: * -> * -> *) a (n :: Nat).
(PrimMonad m, MVector v a) =>
MVector v n (PrimState m) a -> MVector v n (PrimState m) a -> m ()
VGM.move
{-# inline move #-}

-- | Convert a 'Data.Vector.Storable.Mutable.MVector' into
-- a 'Data.Vector.Storable.Mutable.Sized.MVector' if it has the correct
-- size, otherwise return Nothing.
--
-- Note that this does no copying; the returned 'MVector' is a reference to
-- the exact same vector in memory as the given one, and any modifications
-- to it are also reflected in the given
-- 'Data.Vector.Storable.Mutable.MVector'.
toSized :: forall n a s. (KnownNat n, Storable a)
        => VSM.MVector s a -> Maybe (MVector n s a)
toSized :: MVector s a -> Maybe (MVector n s a)
toSized = MVector s a -> Maybe (MVector n s a)
forall (v :: * -> * -> *) (n :: Nat) s a.
(MVector v a, KnownNat n) =>
v s a -> Maybe (MVector v n s a)
VGM.toSized
{-# inline toSized #-}

-- | Takes a 'Data.Vector.Storable.Mutable.MVector' and returns
-- a continuation providing a 'Data.Vector.Storable.Mutable.Sized.MVector'
-- with a size parameter @n@ that is determined at runtime based on the
-- length of the input vector.
--
-- Essentially converts a 'Data.Vector.Storable.Mutable.MVector' into
-- a 'Data.Vector.Storable.Sized.MVector' with the correct size parameter
-- @n@.
--
-- Note that this does no copying; the returned 'MVector' is a reference to
-- the exact same vector in memory as the given one, and any modifications
-- to it are also reflected in the given
-- 'Data.Vector.Storable.Mutable.MVector'.
withSized :: forall s a r. Storable a
          => VSM.MVector s a -> (forall n. KnownNat n => MVector n s a -> r) -> r
withSized :: MVector s a
-> (forall (n :: Nat). KnownNat n => MVector n s a -> r) -> r
withSized = MVector s a
-> (forall (n :: Nat). KnownNat n => MVector n s a -> r) -> r
forall (v :: * -> * -> *) s a r.
MVector v a =>
v s a
-> (forall (n :: Nat). KnownNat n => MVector v n s a -> r) -> r
VGM.withSized
{-# inline withSized #-}

-- | Convert a 'Data.Vector.Storable.Mutable.Sized.MVector' into a
-- 'Data.Vector.Storable.Mutable.MVector'.
--
-- Note that this does no copying; the returned
-- 'Data.Vector.Storable.Mutable.MVector' is a reference to the exact same
-- vector in memory as the given one, and any modifications to it are also
-- reflected in the given 'MVector'.
fromSized :: MVector n s a -> VSM.MVector s a
fromSized :: MVector n s a -> MVector s a
fromSized = MVector n s a -> MVector s a
forall (v :: * -> * -> *) (n :: Nat) s a. MVector v n s a -> v s a
VGM.fromSized
{-# inline fromSized #-}