-- |
-- Copyright: (C) 2013 Amgen, Inc.
--                2016 Tweag I/O Limited.
--
-- Vectors that can be passed to and from R with no copying at all. These
-- vectors are wrappers over SEXP vectors used by R. Memory for vectors is
-- allocated from the R heap, and in such way that they can be converted to
-- a 'SEXP' by simple pointer arithmetic (see 'toSEXP').
--
-- Like "Data.Vector.Storable.Mutable" vectors, the vector type in this module
-- adds one extra level of indirection and a small amount of storage overhead
-- for maintainging lengths and slice offsets. If you're keeping a very large
-- number of tiny vectors in memory, you're better off keeping them as 'SEXP's
-- and calling 'fromSEXP' on-the-fly.

{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}

module Data.Vector.SEXP.Mutable
  ( -- * Mutable slices of 'SEXP' vector types
    MVector
  , fromSEXP
  , toSEXP
  , release
  , unsafeRelease
    -- * Accessors
    -- ** Length information
  , length
  , null
    -- * Construction
    -- ** Initialisation
  , new
  , unsafeNew
  , replicate
  , replicateM
  , clone
    -- ** Extracting subvectors
  , slice
  , init
  , tail
  , take
  , drop
  , splitAt
  , unsafeSlice
  , unsafeInit
  , unsafeTail
  , unsafeTake
  , unsafeDrop
    -- ** Overlapping
  , overlaps
    -- ** Restricting memory usage
  , clear
    -- * Accessing individual elements
  , read
  , write
  , swap
  , unsafeRead
  , unsafeWrite
  , unsafeSwap
    -- * Modifying vectors
    -- ** Filling and copying
  , set
  , copy
  , move
  , unsafeCopy
  , unsafeMove
  ) where

import Control.Monad.R.Class
import Control.Monad.R.Internal
import Data.Vector.SEXP.Base
import Data.Vector.SEXP.Mutable.Internal
import qualified Foreign.R as R
import Foreign.R (SEXP)
import Internal.Error

import qualified Data.Vector.Generic.Mutable as G

import Control.Applicative
import Control.Arrow ((>>>), (***))
import Data.Proxy (Proxy(..))
import Data.Reflection (Reifies(..), reify)
import System.IO.Unsafe (unsafePerformIO)

import Prelude hiding
  ( length, drop, init, null, read, replicate, splitAt, tail, take )

-- Internal helpers
-- ----------------

phony
  :: forall s ty a b.
     (VECTOR s ty a)
  => (forall t. Reifies t (AcquireIO s) => W t ty s a -> b)
  -> MVector s ty a
  -> b
phony :: forall s (ty :: SEXPTYPE) a b.
VECTOR s ty a =>
(forall t. Reifies t (AcquireIO s) => W t ty s a -> b)
-> MVector s ty a -> b
phony forall t. Reifies t (AcquireIO s) => W t ty s a -> b
f MVector s ty a
v =
    forall a r. a -> (forall s. Reifies s a => Proxy s -> r) -> r
reify (forall s.
(forall (ty :: SEXPTYPE). SEXP V ty -> IO (SEXP s ty))
-> AcquireIO s
AcquireIO forall {a}. a
acquireIO) forall a b. (a -> b) -> a -> b
$ \(Proxy s
Proxy :: Proxy t) -> do
      forall t. Reifies t (AcquireIO s) => W t ty s a -> b
f (forall t (ty :: SEXPTYPE) s a. MVector s ty a -> W t ty s a
W MVector s ty a
v :: W t ty s a)
  where
    acquireIO :: a
acquireIO = forall a. String -> String -> a
violation String
"phony" String
"phony acquire called."

phony2
  :: forall s ty a b.
     (VECTOR s ty a)
  => (forall t. Reifies t (AcquireIO s) => W t ty s a -> W t ty s a -> b)
  -> MVector s ty a
  -> MVector s ty a
  -> b
phony2 :: forall s (ty :: SEXPTYPE) a b.
VECTOR s ty a =>
(forall t.
 Reifies t (AcquireIO s) =>
 W t ty s a -> W t ty s a -> b)
-> MVector s ty a -> MVector s ty a -> b
phony2 forall t. Reifies t (AcquireIO s) => W t ty s a -> W t ty s a -> b
f MVector s ty a
v1 MVector s ty a
v2 =
    forall a r. a -> (forall s. Reifies s a => Proxy s -> r) -> r
reify (forall s.
(forall (ty :: SEXPTYPE). SEXP V ty -> IO (SEXP s ty))
-> AcquireIO s
AcquireIO forall {a}. a
acquireIO) forall a b. (a -> b) -> a -> b
$ \(Proxy s
Proxy :: Proxy t) -> do
      forall t. Reifies t (AcquireIO s) => W t ty s a -> W t ty s a -> b
f (forall t (ty :: SEXPTYPE) s a. MVector s ty a -> W t ty s a
W forall a b. (a -> b) -> a -> b
$ MVector s ty a
v1 :: W t ty s a)
        (forall t (ty :: SEXPTYPE) s a. MVector s ty a -> W t ty s a
W forall a b. (a -> b) -> a -> b
$ MVector s ty a
v2 :: W t ty s a)
  where
    acquireIO :: a
acquireIO = forall a. String -> String -> a
violation String
"phony2" String
"phony acquire called."

-- Conversions
-- -----------

-- | /O(1)/ Create a vector from a 'SEXP'.
fromSEXP :: VECTOR s ty a => SEXP s ty -> MVector s ty a
fromSEXP :: forall s (ty :: SEXPTYPE) a.
VECTOR s ty a =>
SEXP s ty -> MVector s ty a
fromSEXP SEXP s ty
sx =
    forall s (ty :: SEXPTYPE) a.
SEXP s ty -> Int32 -> Int32 -> MVector s ty a
MVector SEXP s ty
sx Int32
0 forall a b. (a -> b) -> a -> b
$ forall a. IO a -> a
unsafePerformIO forall a b. (a -> b) -> a -> b
$ do
      forall a b. (Integral a, Num b) => a -> b
fromIntegral forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (a :: SEXPTYPE) s. IsVector a => SEXP s a -> IO CInt
R.length SEXP s ty
sx

-- | /O(1)/ in the common case, /O(n)/ for proper slices. Convert a mutable
-- vector to a 'SEXP'. This can be done efficiently, without copy, because
-- vectors in this module always include a 'SEXP' header immediately before the
-- vector data in memory.
toSEXP
  :: (MonadR m, VECTOR (Region m) ty a)
  => MVector (Region m) ty a
  -> m (SEXP (Region m) ty)
toSEXP :: forall (m :: * -> *) (ty :: SEXPTYPE) a.
(MonadR m, VECTOR (Region m) ty a) =>
MVector (Region m) ty a -> m (SEXP (Region m) ty)
toSEXP (MVector SEXP (Region m) ty
sx Int32
0 Int32
len)
  | Int32
len forall a. Eq a => a -> a -> Bool
== Int32
sexplen = forall (m :: * -> *) a. Monad m => a -> m a
return SEXP (Region m) ty
sx
  where
    sexplen :: Int32
sexplen = forall a. IO a -> a
unsafePerformIO forall a b. (a -> b) -> a -> b
$ do
      forall a b. (Integral a, Num b) => a -> b
fromIntegral forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (a :: SEXPTYPE) s. IsVector a => SEXP s a -> IO CInt
R.length SEXP (Region m) ty
sx
toSEXP MVector (Region m) ty a
v = forall (m :: * -> *) (ty :: SEXPTYPE) a.
(MonadR m, VECTOR (Region m) ty a) =>
MVector (Region m) ty a -> m (SEXP (Region m) ty)
toSEXP forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall (m :: * -> *) (ty :: SEXPTYPE) a.
(MonadR m, VECTOR (Region m) ty a) =>
MVector (Region m) ty a -> m (MVector (Region m) ty a)
clone MVector (Region m) ty a
v -- yield a zero based slice.

-- Length information
-- ------------------

-- | Length of the mutable vector.
length :: VECTOR s ty a => MVector s ty a -> Int
{-# INLINE length #-}
length :: forall s (ty :: SEXPTYPE) a. VECTOR s ty a => MVector s ty a -> Int
length = forall s (ty :: SEXPTYPE) a b.
VECTOR s ty a =>
(forall t. Reifies t (AcquireIO s) => W t ty s a -> b)
-> MVector s ty a -> b
phony forall (v :: * -> * -> *) a s. MVector v a => v s a -> Int
G.length

-- | Check whether the vector is empty.
null :: VECTOR s ty a => MVector s ty a -> Bool
{-# INLINE null #-}
null :: forall s (ty :: SEXPTYPE) a.
VECTOR s ty a =>
MVector s ty a -> Bool
null = forall s (ty :: SEXPTYPE) a b.
VECTOR s ty a =>
(forall t. Reifies t (AcquireIO s) => W t ty s a -> b)
-> MVector s ty a -> b
phony forall (v :: * -> * -> *) a s. MVector v a => v s a -> Bool
G.null

-- Extracting subvectors
-- ---------------------

-- | Yield a part of the mutable vector without copying it.
slice :: VECTOR s ty a => Int -> Int -> MVector s ty a -> MVector s ty a
{-# INLINE slice #-}
slice :: forall s (ty :: SEXPTYPE) a.
VECTOR s ty a =>
Int -> Int -> MVector s ty a -> MVector s ty a
slice Int
i Int
j = forall s (ty :: SEXPTYPE) a b.
VECTOR s ty a =>
(forall t. Reifies t (AcquireIO s) => W t ty s a -> b)
-> MVector s ty a -> b
phony (forall t (ty :: SEXPTYPE) s a. W t ty s a -> MVector s ty a
unW forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (v :: * -> * -> *) a s.
MVector v a =>
Int -> Int -> v s a -> v s a
G.slice Int
i Int
j)

take :: VECTOR s ty a => Int -> MVector s ty a -> MVector s ty a
{-# INLINE take #-}
take :: forall s (ty :: SEXPTYPE) a.
VECTOR s ty a =>
Int -> MVector s ty a -> MVector s ty a
take Int
n = forall s (ty :: SEXPTYPE) a b.
VECTOR s ty a =>
(forall t. Reifies t (AcquireIO s) => W t ty s a -> b)
-> MVector s ty a -> b
phony (forall t (ty :: SEXPTYPE) s a. W t ty s a -> MVector s ty a
unW forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (v :: * -> * -> *) a s. MVector v a => Int -> v s a -> v s a
G.take Int
n)

drop :: VECTOR s ty a => Int -> MVector s ty a -> MVector s ty a
{-# INLINE drop #-}
drop :: forall s (ty :: SEXPTYPE) a.
VECTOR s ty a =>
Int -> MVector s ty a -> MVector s ty a
drop Int
n = forall s (ty :: SEXPTYPE) a b.
VECTOR s ty a =>
(forall t. Reifies t (AcquireIO s) => W t ty s a -> b)
-> MVector s ty a -> b
phony (forall t (ty :: SEXPTYPE) s a. W t ty s a -> MVector s ty a
unW forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (v :: * -> * -> *) a s. MVector v a => Int -> v s a -> v s a
G.drop Int
n)

splitAt :: VECTOR s ty a => Int -> MVector s ty a -> (MVector s ty a, MVector s ty a)
{-# INLINE splitAt #-}
splitAt :: forall s (ty :: SEXPTYPE) a.
VECTOR s ty a =>
Int -> MVector s ty a -> (MVector s ty a, MVector s ty a)
splitAt Int
n = forall s (ty :: SEXPTYPE) a b.
VECTOR s ty a =>
(forall t. Reifies t (AcquireIO s) => W t ty s a -> b)
-> MVector s ty a -> b
phony (forall (v :: * -> * -> *) a s.
MVector v a =>
Int -> v s a -> (v s a, v s a)
G.splitAt Int
n forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> forall t (ty :: SEXPTYPE) s a. W t ty s a -> MVector s ty a
unW forall (a :: * -> * -> *) b c b' c'.
Arrow a =>
a b c -> a b' c' -> a (b, b') (c, c')
*** forall t (ty :: SEXPTYPE) s a. W t ty s a -> MVector s ty a
unW)

init :: VECTOR s ty a => MVector s ty a -> MVector s ty a
{-# INLINE init #-}
init :: forall s (ty :: SEXPTYPE) a.
VECTOR s ty a =>
MVector s ty a -> MVector s ty a
init = forall s (ty :: SEXPTYPE) a b.
VECTOR s ty a =>
(forall t. Reifies t (AcquireIO s) => W t ty s a -> b)
-> MVector s ty a -> b
phony (forall t (ty :: SEXPTYPE) s a. W t ty s a -> MVector s ty a
unW forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (v :: * -> * -> *) a s. MVector v a => v s a -> v s a
G.init)

tail :: VECTOR s ty a => MVector s ty a -> MVector s ty a
{-# INLINE tail #-}
tail :: forall s (ty :: SEXPTYPE) a.
VECTOR s ty a =>
MVector s ty a -> MVector s ty a
tail = forall s (ty :: SEXPTYPE) a b.
VECTOR s ty a =>
(forall t. Reifies t (AcquireIO s) => W t ty s a -> b)
-> MVector s ty a -> b
phony (forall t (ty :: SEXPTYPE) s a. W t ty s a -> MVector s ty a
unW forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (v :: * -> * -> *) a s. MVector v a => v s a -> v s a
G.tail)

-- | Yield a part of the mutable vector without copying it. No bounds checks
-- are performed.
unsafeSlice :: VECTOR s ty a
            => Int  -- ^ starting index
            -> Int  -- ^ length of the slice
            -> MVector s ty a
            -> MVector s ty a
{-# INLINE unsafeSlice #-}
unsafeSlice :: forall s (ty :: SEXPTYPE) a.
VECTOR s ty a =>
Int -> Int -> MVector s ty a -> MVector s ty a
unsafeSlice Int
i Int
j = forall s (ty :: SEXPTYPE) a b.
VECTOR s ty a =>
(forall t. Reifies t (AcquireIO s) => W t ty s a -> b)
-> MVector s ty a -> b
phony (forall t (ty :: SEXPTYPE) s a. W t ty s a -> MVector s ty a
unW forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (v :: * -> * -> *) a s.
MVector v a =>
Int -> Int -> v s a -> v s a
G.unsafeSlice Int
i Int
j)

unsafeTake :: VECTOR s ty a => Int -> MVector s ty a -> MVector s ty a
{-# INLINE unsafeTake #-}
unsafeTake :: forall s (ty :: SEXPTYPE) a.
VECTOR s ty a =>
Int -> MVector s ty a -> MVector s ty a
unsafeTake Int
n = forall s (ty :: SEXPTYPE) a b.
VECTOR s ty a =>
(forall t. Reifies t (AcquireIO s) => W t ty s a -> b)
-> MVector s ty a -> b
phony (forall t (ty :: SEXPTYPE) s a. W t ty s a -> MVector s ty a
unW forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (v :: * -> * -> *) a s. MVector v a => Int -> v s a -> v s a
G.unsafeTake Int
n)

unsafeDrop :: VECTOR s ty a => Int -> MVector s ty a -> MVector s ty a
{-# INLINE unsafeDrop #-}
unsafeDrop :: forall s (ty :: SEXPTYPE) a.
VECTOR s ty a =>
Int -> MVector s ty a -> MVector s ty a
unsafeDrop Int
n = forall s (ty :: SEXPTYPE) a b.
VECTOR s ty a =>
(forall t. Reifies t (AcquireIO s) => W t ty s a -> b)
-> MVector s ty a -> b
phony (forall t (ty :: SEXPTYPE) s a. W t ty s a -> MVector s ty a
unW forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (v :: * -> * -> *) a s. MVector v a => Int -> v s a -> v s a
G.unsafeDrop Int
n)

unsafeInit :: VECTOR s ty a => MVector s ty a -> MVector s ty a
{-# INLINE unsafeInit #-}
unsafeInit :: forall s (ty :: SEXPTYPE) a.
VECTOR s ty a =>
MVector s ty a -> MVector s ty a
unsafeInit = forall s (ty :: SEXPTYPE) a b.
VECTOR s ty a =>
(forall t. Reifies t (AcquireIO s) => W t ty s a -> b)
-> MVector s ty a -> b
phony (forall t (ty :: SEXPTYPE) s a. W t ty s a -> MVector s ty a
unW forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (v :: * -> * -> *) a s. MVector v a => v s a -> v s a
G.unsafeInit)

unsafeTail :: VECTOR s ty a => MVector s ty a -> MVector s ty a
{-# INLINE unsafeTail #-}
unsafeTail :: forall s (ty :: SEXPTYPE) a.
VECTOR s ty a =>
MVector s ty a -> MVector s ty a
unsafeTail = forall s (ty :: SEXPTYPE) a b.
VECTOR s ty a =>
(forall t. Reifies t (AcquireIO s) => W t ty s a -> b)
-> MVector s ty a -> b
phony (forall t (ty :: SEXPTYPE) s a. W t ty s a -> MVector s ty a
unW forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (v :: * -> * -> *) a s. MVector v a => v s a -> v s a
G.unsafeTail)

-- Overlapping
-- -----------

-- | Check whether two vectors overlap.
overlaps :: VECTOR s ty a => MVector s ty a -> MVector s ty a -> Bool
{-# INLINE overlaps #-}
overlaps :: forall s (ty :: SEXPTYPE) a.
VECTOR s ty a =>
MVector s ty a -> MVector s ty a -> Bool
overlaps = forall s (ty :: SEXPTYPE) a b.
VECTOR s ty a =>
(forall t.
 Reifies t (AcquireIO s) =>
 W t ty s a -> W t ty s a -> b)
-> MVector s ty a -> MVector s ty a -> b
phony2 forall (v :: * -> * -> *) a s.
MVector v a =>
v s a -> v s a -> Bool
G.overlaps

-- Initialisation
-- --------------

-- | Create a mutable vector of the given length.
new :: forall m ty a.
       (MonadR m, VECTOR (Region m) ty a)
    => Int
    -> m (MVector (Region m) ty a)
{-# INLINE new #-}
new :: forall (m :: * -> *) (ty :: SEXPTYPE) a.
(MonadR m, VECTOR (Region m) ty a) =>
Int -> m (MVector (Region m) ty a)
new Int
n = forall (m :: * -> *) r.
MonadR m =>
(forall s. Reifies s (AcquireIO (Region m)) => Proxy s -> m r)
-> m r
withAcquire forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) t (ty :: SEXPTYPE) s a (proxy :: * -> *).
Monad m =>
m (W t ty s a) -> proxy t -> m (MVector s ty a)
proxyW forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) (v :: * -> * -> *) a.
(PrimMonad m, MVector v a) =>
Int -> m (v (PrimState m) a)
G.new Int
n

-- | Create a mutable vector of the given length. The length is not checked.
unsafeNew :: (MonadR m, VECTOR (Region m) ty a) => Int -> m (MVector (Region m) ty a)
{-# INLINE unsafeNew #-}
unsafeNew :: forall (m :: * -> *) (ty :: SEXPTYPE) a.
(MonadR m, VECTOR (Region m) ty a) =>
Int -> m (MVector (Region m) ty a)
unsafeNew Int
n = forall (m :: * -> *) r.
MonadR m =>
(forall s. Reifies s (AcquireIO (Region m)) => Proxy s -> m r)
-> m r
withAcquire forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) t (ty :: SEXPTYPE) s a (proxy :: * -> *).
Monad m =>
m (W t ty s a) -> proxy t -> m (MVector s ty a)
proxyW forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) (v :: * -> * -> *) a.
(PrimMonad m, MVector v a) =>
Int -> m (v (PrimState m) a)
G.unsafeNew Int
n

-- | Create a mutable vector of the given length (0 if the length is negative)
-- and fill it with an initial value.
replicate :: (MonadR m, VECTOR (Region m) ty a) => Int -> a -> m (MVector (Region m) ty a)
{-# INLINE replicate #-}
replicate :: forall (m :: * -> *) (ty :: SEXPTYPE) a.
(MonadR m, VECTOR (Region m) ty a) =>
Int -> a -> m (MVector (Region m) ty a)
replicate Int
n a
x = forall (m :: * -> *) r.
MonadR m =>
(forall s. Reifies s (AcquireIO (Region m)) => Proxy s -> m r)
-> m r
withAcquire forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) t (ty :: SEXPTYPE) s a (proxy :: * -> *).
Monad m =>
m (W t ty s a) -> proxy t -> m (MVector s ty a)
proxyW forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) (v :: * -> * -> *) a.
(PrimMonad m, MVector v a) =>
Int -> a -> m (v (PrimState m) a)
G.replicate Int
n a
x

-- | Create a mutable vector of the given length (0 if the length is negative)
-- and fill it with values produced by repeatedly executing the monadic action.
replicateM :: (MonadR m, VECTOR (Region m) ty a) => Int -> m a -> m (MVector (Region m) ty a)
{-# INLINE replicateM #-}
replicateM :: forall (m :: * -> *) (ty :: SEXPTYPE) a.
(MonadR m, VECTOR (Region m) ty a) =>
Int -> m a -> m (MVector (Region m) ty a)
replicateM Int
n m a
m = forall (m :: * -> *) r.
MonadR m =>
(forall s. Reifies s (AcquireIO (Region m)) => Proxy s -> m r)
-> m r
withAcquire forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) t (ty :: SEXPTYPE) s a (proxy :: * -> *).
Monad m =>
m (W t ty s a) -> proxy t -> m (MVector s ty a)
proxyW forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) (v :: * -> * -> *) a.
(PrimMonad m, MVector v a) =>
Int -> m a -> m (v (PrimState m) a)
G.replicateM Int
n m a
m

-- | Create a copy of a mutable vector.
clone :: (MonadR m, VECTOR (Region m) ty a)
      => MVector (Region m) ty a
      -> m (MVector (Region m) ty a)
{-# INLINE clone #-}
clone :: forall (m :: * -> *) (ty :: SEXPTYPE) a.
(MonadR m, VECTOR (Region m) ty a) =>
MVector (Region m) ty a -> m (MVector (Region m) ty a)
clone MVector (Region m) ty a
v = forall (m :: * -> *) r.
MonadR m =>
(forall s. Reifies s (AcquireIO (Region m)) => Proxy s -> m r)
-> m r
withAcquire forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) t (ty :: SEXPTYPE) s a (proxy :: * -> *).
Monad m =>
m (W t ty s a) -> proxy t -> m (MVector s ty a)
proxyW forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) (v :: * -> * -> *) a.
(PrimMonad m, MVector v a) =>
v (PrimState m) a -> m (v (PrimState m) a)
G.clone (forall t (ty :: SEXPTYPE) s a. MVector s ty a -> W t ty s a
W MVector (Region m) ty a
v)

-- Restricting memory usage
-- ------------------------

-- | Reset all elements of the vector to some undefined value, clearing all
-- references to external objects. This is usually a noop for unboxed vectors.
clear :: (MonadR m, VECTOR (Region m) ty a) => MVector (Region m) ty a -> m ()
{-# INLINE clear #-}
clear :: forall (m :: * -> *) (ty :: SEXPTYPE) a.
(MonadR m, VECTOR (Region m) ty a) =>
MVector (Region m) ty a -> m ()
clear MVector (Region m) ty a
v = forall (m :: * -> *) r.
MonadR m =>
(forall s. Reifies s (AcquireIO (Region m)) => Proxy s -> m r)
-> m r
withAcquire forall a b. (a -> b) -> a -> b
$ \Proxy s
p -> forall (m :: * -> *) (v :: * -> * -> *) a.
(PrimMonad m, MVector v a) =>
v (PrimState m) a -> m ()
G.clear (forall (proxy :: * -> *) t s (ty :: SEXPTYPE) a.
proxy t -> MVector s ty a -> W t ty s a
withW Proxy s
p MVector (Region m) ty a
v)

-- Accessing individual elements
-- -----------------------------

-- | Yield the element at the given position.
read :: (MonadR m, VECTOR (Region m) ty a)
     => MVector (Region m) ty a -> Int -> m a
{-# INLINE read #-}
read :: forall (m :: * -> *) (ty :: SEXPTYPE) a.
(MonadR m, VECTOR (Region m) ty a) =>
MVector (Region m) ty a -> Int -> m a
read MVector (Region m) ty a
v Int
i = forall (m :: * -> *) r.
MonadR m =>
(forall s. Reifies s (AcquireIO (Region m)) => Proxy s -> m r)
-> m r
withAcquire forall a b. (a -> b) -> a -> b
$ \Proxy s
p -> forall (m :: * -> *) (v :: * -> * -> *) a.
(PrimMonad m, MVector v a) =>
v (PrimState m) a -> Int -> m a
G.read (forall (proxy :: * -> *) t s (ty :: SEXPTYPE) a.
proxy t -> MVector s ty a -> W t ty s a
withW Proxy s
p MVector (Region m) ty a
v) Int
i

-- | Replace the element at the given position.
write :: (MonadR m, VECTOR (Region m) ty a)
      => MVector (Region m) ty a -> Int -> a -> m ()
{-# INLINE write #-}
write :: forall (m :: * -> *) (ty :: SEXPTYPE) a.
(MonadR m, VECTOR (Region m) ty a) =>
MVector (Region m) ty a -> Int -> a -> m ()
write MVector (Region m) ty a
v Int
i a
x = forall (m :: * -> *) r.
MonadR m =>
(forall s. Reifies s (AcquireIO (Region m)) => Proxy s -> m r)
-> m r
withAcquire forall a b. (a -> b) -> a -> b
$ \Proxy s
p -> forall (m :: * -> *) (v :: * -> * -> *) a.
(PrimMonad m, MVector v a) =>
v (PrimState m) a -> Int -> a -> m ()
G.write (forall (proxy :: * -> *) t s (ty :: SEXPTYPE) a.
proxy t -> MVector s ty a -> W t ty s a
withW Proxy s
p MVector (Region m) ty a
v) Int
i a
x

-- | Swap the elements at the given positions.
swap :: (MonadR m, VECTOR (Region m) ty a)
     => MVector (Region m) ty a -> Int -> Int -> m ()
{-# INLINE swap #-}
swap :: forall (m :: * -> *) (ty :: SEXPTYPE) a.
(MonadR m, VECTOR (Region m) ty a) =>
MVector (Region m) ty a -> Int -> Int -> m ()
swap MVector (Region m) ty a
v Int
i Int
j = forall (m :: * -> *) r.
MonadR m =>
(forall s. Reifies s (AcquireIO (Region m)) => Proxy s -> m r)
-> m r
withAcquire forall a b. (a -> b) -> a -> b
$ \Proxy s
p -> forall (m :: * -> *) (v :: * -> * -> *) a.
(PrimMonad m, MVector v a) =>
v (PrimState m) a -> Int -> Int -> m ()
G.swap (forall (proxy :: * -> *) t s (ty :: SEXPTYPE) a.
proxy t -> MVector s ty a -> W t ty s a
withW Proxy s
p MVector (Region m) ty a
v) Int
i Int
j

-- | Yield the element at the given position. No bounds checks are performed.
unsafeRead :: (MonadR m, VECTOR (Region m) ty a)
           => MVector (Region m) ty a -> Int -> m a
{-# INLINE unsafeRead #-}
unsafeRead :: forall (m :: * -> *) (ty :: SEXPTYPE) a.
(MonadR m, VECTOR (Region m) ty a) =>
MVector (Region m) ty a -> Int -> m a
unsafeRead MVector (Region m) ty a
v Int
i = forall (m :: * -> *) r.
MonadR m =>
(forall s. Reifies s (AcquireIO (Region m)) => Proxy s -> m r)
-> m r
withAcquire forall a b. (a -> b) -> a -> b
$ \Proxy s
p -> forall (m :: * -> *) (v :: * -> * -> *) a.
(PrimMonad m, MVector v a) =>
v (PrimState m) a -> Int -> m a
G.unsafeRead (forall (proxy :: * -> *) t s (ty :: SEXPTYPE) a.
proxy t -> MVector s ty a -> W t ty s a
withW Proxy s
p MVector (Region m) ty a
v) Int
i

-- | Replace the element at the given position. No bounds checks are performed.
unsafeWrite :: (MonadR m, VECTOR (Region m) ty a)
            => MVector (Region m) ty a -> Int -> a -> m ()
{-# INLINE unsafeWrite #-}
unsafeWrite :: forall (m :: * -> *) (ty :: SEXPTYPE) a.
(MonadR m, VECTOR (Region m) ty a) =>
MVector (Region m) ty a -> Int -> a -> m ()
unsafeWrite MVector (Region m) ty a
v Int
i a
x = forall (m :: * -> *) r.
MonadR m =>
(forall s. Reifies s (AcquireIO (Region m)) => Proxy s -> m r)
-> m r
withAcquire forall a b. (a -> b) -> a -> b
$ \Proxy s
p -> forall (m :: * -> *) (v :: * -> * -> *) a.
(PrimMonad m, MVector v a) =>
v (PrimState m) a -> Int -> a -> m ()
G.unsafeWrite (forall (proxy :: * -> *) t s (ty :: SEXPTYPE) a.
proxy t -> MVector s ty a -> W t ty s a
withW Proxy s
p MVector (Region m) ty a
v) Int
i a
x

-- | Swap the elements at the given positions. No bounds checks are performed.
unsafeSwap :: (MonadR m, VECTOR (Region m) ty a)
           => MVector (Region m) ty a -> Int -> Int -> m ()
{-# INLINE unsafeSwap #-}
unsafeSwap :: forall (m :: * -> *) (ty :: SEXPTYPE) a.
(MonadR m, VECTOR (Region m) ty a) =>
MVector (Region m) ty a -> Int -> Int -> m ()
unsafeSwap MVector (Region m) ty a
v Int
i Int
j = forall (m :: * -> *) r.
MonadR m =>
(forall s. Reifies s (AcquireIO (Region m)) => Proxy s -> m r)
-> m r
withAcquire forall a b. (a -> b) -> a -> b
$ \Proxy s
p -> forall (m :: * -> *) (v :: * -> * -> *) a.
(PrimMonad m, MVector v a) =>
v (PrimState m) a -> Int -> Int -> m ()
G.unsafeSwap (forall (proxy :: * -> *) t s (ty :: SEXPTYPE) a.
proxy t -> MVector s ty a -> W t ty s a
withW Proxy s
p MVector (Region m) ty a
v) Int
i Int
j

-- Filling and copying
-- -------------------

-- | Set all elements of the vector to the given value.
set :: (MonadR m, VECTOR (Region m) ty a) => MVector (Region m) ty a -> a -> m ()
{-# INLINE set #-}
set :: forall (m :: * -> *) (ty :: SEXPTYPE) a.
(MonadR m, VECTOR (Region m) ty a) =>
MVector (Region m) ty a -> a -> m ()
set MVector (Region m) ty a
v a
x = forall (m :: * -> *) r.
MonadR m =>
(forall s. Reifies s (AcquireIO (Region m)) => Proxy s -> m r)
-> m r
withAcquire forall a b. (a -> b) -> a -> b
$ \Proxy s
p -> forall (m :: * -> *) (v :: * -> * -> *) a.
(PrimMonad m, MVector v a) =>
v (PrimState m) a -> a -> m ()
G.set (forall (proxy :: * -> *) t s (ty :: SEXPTYPE) a.
proxy t -> MVector s ty a -> W t ty s a
withW Proxy s
p MVector (Region m) ty a
v) a
x

-- | Copy a vector. The two vectors must have the same length and may not
-- overlap.
copy :: (MonadR m, VECTOR (Region m) ty a)
     => MVector (Region m) ty a
     -> MVector (Region m) ty a
     -> m ()
{-# INLINE copy #-}
copy :: forall (m :: * -> *) (ty :: SEXPTYPE) a.
(MonadR m, VECTOR (Region m) ty a) =>
MVector (Region m) ty a -> MVector (Region m) ty a -> m ()
copy MVector (Region m) ty a
v1 MVector (Region m) ty a
v2 = forall (m :: * -> *) r.
MonadR m =>
(forall s. Reifies s (AcquireIO (Region m)) => Proxy s -> m r)
-> m r
withAcquire forall a b. (a -> b) -> a -> b
$ \Proxy s
p -> forall (m :: * -> *) (v :: * -> * -> *) a.
(PrimMonad m, MVector v a) =>
v (PrimState m) a -> v (PrimState m) a -> m ()
G.copy (forall (proxy :: * -> *) t s (ty :: SEXPTYPE) a.
proxy t -> MVector s ty a -> W t ty s a
withW Proxy s
p MVector (Region m) ty a
v1) (forall (proxy :: * -> *) t s (ty :: SEXPTYPE) a.
proxy t -> MVector s ty a -> W t ty s a
withW Proxy s
p MVector (Region m) ty a
v2)

-- | Copy a vector. The two vectors must have the same length and may not
-- overlap. This is not checked.
unsafeCopy :: (MonadR m, VECTOR (Region m) ty a)
           => MVector (Region m) ty a   -- ^ target
           -> MVector (Region m) ty a   -- ^ source
           -> m ()
{-# INLINE unsafeCopy #-}
unsafeCopy :: forall (m :: * -> *) (ty :: SEXPTYPE) a.
(MonadR m, VECTOR (Region m) ty a) =>
MVector (Region m) ty a -> MVector (Region m) ty a -> m ()
unsafeCopy MVector (Region m) ty a
v1 MVector (Region m) ty a
v2 = forall (m :: * -> *) r.
MonadR m =>
(forall s. Reifies s (AcquireIO (Region m)) => Proxy s -> m r)
-> m r
withAcquire forall a b. (a -> b) -> a -> b
$ \Proxy s
p -> forall (m :: * -> *) (v :: * -> * -> *) a.
(PrimMonad m, MVector v a) =>
v (PrimState m) a -> v (PrimState m) a -> m ()
G.unsafeCopy (forall (proxy :: * -> *) t s (ty :: SEXPTYPE) a.
proxy t -> MVector s ty a -> W t ty s a
withW Proxy s
p MVector (Region m) ty a
v1) (forall (proxy :: * -> *) t s (ty :: SEXPTYPE) a.
proxy t -> MVector s ty a -> W t ty s a
withW Proxy s
p MVector (Region m) ty a
v2)

-- | Move the contents of a vector. The two vectors must have the same
-- length.
--
-- If the vectors do not overlap, then 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 :: (MonadR m, VECTOR (Region m) ty a)
     => MVector (Region m) ty a
     -> MVector (Region m) ty a
     -> m ()
{-# INLINE move #-}
move :: forall (m :: * -> *) (ty :: SEXPTYPE) a.
(MonadR m, VECTOR (Region m) ty a) =>
MVector (Region m) ty a -> MVector (Region m) ty a -> m ()
move MVector (Region m) ty a
v1 MVector (Region m) ty a
v2 = forall (m :: * -> *) r.
MonadR m =>
(forall s. Reifies s (AcquireIO (Region m)) => Proxy s -> m r)
-> m r
withAcquire forall a b. (a -> b) -> a -> b
$ \Proxy s
p -> forall (m :: * -> *) (v :: * -> * -> *) a.
(PrimMonad m, MVector v a) =>
v (PrimState m) a -> v (PrimState m) a -> m ()
G.move (forall (proxy :: * -> *) t s (ty :: SEXPTYPE) a.
proxy t -> MVector s ty a -> W t ty s a
withW Proxy s
p MVector (Region m) ty a
v1) (forall (proxy :: * -> *) t s (ty :: SEXPTYPE) a.
proxy t -> MVector s ty a -> W t ty s a
withW Proxy s
p MVector (Region m) ty a
v2)

-- | Move the contents of a vector. The two vectors must have the same
-- length, but this is not checked.
--
-- If the vectors do not overlap, then this is equivalent to 'unsafeCopy'.
-- 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.
unsafeMove :: (MonadR m, VECTOR (Region m) ty a)
           => MVector (Region m) ty a             -- ^ target
           -> MVector (Region m) ty a             -- ^ source
           -> m ()
{-# INLINE unsafeMove #-}
unsafeMove :: forall (m :: * -> *) (ty :: SEXPTYPE) a.
(MonadR m, VECTOR (Region m) ty a) =>
MVector (Region m) ty a -> MVector (Region m) ty a -> m ()
unsafeMove MVector (Region m) ty a
v1 MVector (Region m) ty a
v2 = forall (m :: * -> *) r.
MonadR m =>
(forall s. Reifies s (AcquireIO (Region m)) => Proxy s -> m r)
-> m r
withAcquire forall a b. (a -> b) -> a -> b
$ \Proxy s
p -> forall (m :: * -> *) (v :: * -> * -> *) a.
(PrimMonad m, MVector v a) =>
v (PrimState m) a -> v (PrimState m) a -> m ()
G.unsafeMove (forall (proxy :: * -> *) t s (ty :: SEXPTYPE) a.
proxy t -> MVector s ty a -> W t ty s a
withW Proxy s
p MVector (Region m) ty a
v1) (forall (proxy :: * -> *) t s (ty :: SEXPTYPE) a.
proxy t -> MVector s ty a -> W t ty s a
withW Proxy s
p MVector (Region m) ty a
v2)