-- |
-- Module:      Data.Vector.Rotcev
-- Copyright:   (c) 2019 Andrew Lelechenko
-- Licence:     BSD3
-- Maintainer:  Andrew Lelechenko <andrew.lelechenko@gmail.com>
--
-- A wrapper for an arbitrary 'V.Vector' with O(1) 'reverse'.
-- Instead of creating a copy, it just flips a flag, which inverts indexing.
-- Imagine it as a vector with a switch between little-endianness and big-endianness.

{-# LANGUAGE BangPatterns          #-}
{-# LANGUAGE FlexibleContexts      #-}
{-# LANGUAGE FlexibleInstances     #-}
{-# LANGUAGE LambdaCase            #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeFamilies          #-}
{-# LANGUAGE UndecidableInstances  #-}

module Data.Vector.Rotcev
  ( Rotcev(..)
  , reverse
  , unRotcev
  , MRotcev(..)
  , mreverse
  ) where

import Prelude hiding (reverse)
import Data.Function
import Data.Vector.Fusion.Util (Box(..))
import qualified Data.Vector.Generic as V
import qualified Data.Vector.Generic.Mutable as MV

-- | Wrapper for immutable vectors, equipped with a 'V.Vector' instance.
--
-- >>> Forward  (Data.Vector.fromList [0..100]) Data.Vector.Generic.! 10
-- 10
-- >>> Backward (Data.Vector.fromList [0..100]) Data.Vector.Generic.! 10
-- 90
data Rotcev v a
  = Forward  !(v a)
  -- ^ Behaves as an original vector in respect to 'V.Vector' operations.
  | Backward !(v a)
  -- ^ Behaves as a reversed vector in respect to 'V.Vector' operations.
  deriving (Rotcev v a -> Rotcev v a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall (v :: * -> *) a.
Eq (v a) =>
Rotcev v a -> Rotcev v a -> Bool
/= :: Rotcev v a -> Rotcev v a -> Bool
$c/= :: forall (v :: * -> *) a.
Eq (v a) =>
Rotcev v a -> Rotcev v a -> Bool
== :: Rotcev v a -> Rotcev v a -> Bool
$c== :: forall (v :: * -> *) a.
Eq (v a) =>
Rotcev v a -> Rotcev v a -> Bool
Eq, Rotcev v a -> Rotcev v a -> Bool
Rotcev v a -> Rotcev v a -> Ordering
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall {v :: * -> *} {a}. Ord (v a) => Eq (Rotcev v a)
forall (v :: * -> *) a.
Ord (v a) =>
Rotcev v a -> Rotcev v a -> Bool
forall (v :: * -> *) a.
Ord (v a) =>
Rotcev v a -> Rotcev v a -> Ordering
forall (v :: * -> *) a.
Ord (v a) =>
Rotcev v a -> Rotcev v a -> Rotcev v a
min :: Rotcev v a -> Rotcev v a -> Rotcev v a
$cmin :: forall (v :: * -> *) a.
Ord (v a) =>
Rotcev v a -> Rotcev v a -> Rotcev v a
max :: Rotcev v a -> Rotcev v a -> Rotcev v a
$cmax :: forall (v :: * -> *) a.
Ord (v a) =>
Rotcev v a -> Rotcev v a -> Rotcev v a
>= :: Rotcev v a -> Rotcev v a -> Bool
$c>= :: forall (v :: * -> *) a.
Ord (v a) =>
Rotcev v a -> Rotcev v a -> Bool
> :: Rotcev v a -> Rotcev v a -> Bool
$c> :: forall (v :: * -> *) a.
Ord (v a) =>
Rotcev v a -> Rotcev v a -> Bool
<= :: Rotcev v a -> Rotcev v a -> Bool
$c<= :: forall (v :: * -> *) a.
Ord (v a) =>
Rotcev v a -> Rotcev v a -> Bool
< :: Rotcev v a -> Rotcev v a -> Bool
$c< :: forall (v :: * -> *) a.
Ord (v a) =>
Rotcev v a -> Rotcev v a -> Bool
compare :: Rotcev v a -> Rotcev v a -> Ordering
$ccompare :: forall (v :: * -> *) a.
Ord (v a) =>
Rotcev v a -> Rotcev v a -> Ordering
Ord, Int -> Rotcev v a -> ShowS
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall (v :: * -> *) a. Show (v a) => Int -> Rotcev v a -> ShowS
forall (v :: * -> *) a. Show (v a) => [Rotcev v a] -> ShowS
forall (v :: * -> *) a. Show (v a) => Rotcev v a -> String
showList :: [Rotcev v a] -> ShowS
$cshowList :: forall (v :: * -> *) a. Show (v a) => [Rotcev v a] -> ShowS
show :: Rotcev v a -> String
$cshow :: forall (v :: * -> *) a. Show (v a) => Rotcev v a -> String
showsPrec :: Int -> Rotcev v a -> ShowS
$cshowsPrec :: forall (v :: * -> *) a. Show (v a) => Int -> Rotcev v a -> ShowS
Show)

fromRotcev :: Rotcev v a -> v a
fromRotcev :: forall (v :: * -> *) a. Rotcev v a -> v a
fromRotcev = \case
  Forward  v a
v -> v a
v
  Backward v a
v -> v a
v
{-# INLINE fromRotcev #-}

-- | Reverse an immutable vector in O(1) time and space.
--
-- >>> vec = Data.Vector.Generic.fromList [0..100] :: Rotcev Data.Vector.Vector Int
-- >>> reverse vec Data.Vector.Generic.! 10
-- 90
reverse :: Rotcev v a -> Rotcev v a
reverse :: forall (v :: * -> *) a. Rotcev v a -> Rotcev v a
reverse = \case
  Forward  v a
v -> forall (v :: * -> *) a. v a -> Rotcev v a
Backward v a
v
  Backward v a
v -> forall (v :: * -> *) a. v a -> Rotcev v a
Forward  v a
v
{-# INLINE reverse #-}

-- | Unwrap 'Rotcev', extracting an underlying vector.
-- This takes O(1) for 'Forward', but full O(n) time for 'Backward' case,
-- so it would rather be avoided in intermediate computations.
-- Instead leverage opportunities, provided by generic 'V.Vector'
-- and 'MV.MVector' instances.
unRotcev :: V.Vector v a => Rotcev v a -> v a
unRotcev :: forall (v :: * -> *) a. Vector v a => Rotcev v a -> v a
unRotcev = \case
  Forward v a
v  -> v a
v
  Backward v a
v -> forall (v :: * -> *) a. Vector v a => v a -> v a
V.reverse v a
v
{-# INLINE unRotcev #-}

-- | Wrapper for mutable vectors, equipped with a 'MV.MVector' instance.
data MRotcev v s a
  = MForward  !(V.Mutable v s a)
  -- ^ Behaves as an original vector in respect to 'MV.MVector' operations.
  | MBackward !(V.Mutable v s a)
  -- ^ Behaves as a reversed vector in respect to 'MV.MVector' operations.

fromMRotcev :: MRotcev v s a -> V.Mutable v s a
fromMRotcev :: forall (v :: * -> *) s a. MRotcev v s a -> Mutable v s a
fromMRotcev = \case
  MForward  Mutable v s a
v -> Mutable v s a
v
  MBackward Mutable v s a
v -> Mutable v s a
v
{-# INLINE fromMRotcev #-}

-- | Reverse a mutable vector in O(1) time and space.
mreverse :: MRotcev v s a -> MRotcev v s a
mreverse :: forall (v :: * -> *) s a. MRotcev v s a -> MRotcev v s a
mreverse = \case
  MForward  Mutable v s a
v -> forall (v :: * -> *) s a. Mutable v s a -> MRotcev v s a
MBackward Mutable v s a
v
  MBackward Mutable v s a
v -> forall (v :: * -> *) s a. Mutable v s a -> MRotcev v s a
MForward  Mutable v s a
v
{-# INLINE mreverse #-}

type instance V.Mutable (Rotcev v) = MRotcev v

instance MV.MVector (V.Mutable v) a => MV.MVector (MRotcev v) a where
  basicLength :: forall s. MRotcev v s a -> Int
basicLength = forall (v :: * -> * -> *) a s. MVector v a => v s a -> Int
MV.basicLength forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (v :: * -> *) s a. MRotcev v s a -> Mutable v s a
fromMRotcev
  basicUnsafeSlice :: forall s. Int -> Int -> MRotcev v s a -> MRotcev v s a
basicUnsafeSlice Int
off Int
len = \case
    MForward  Mutable v s a
v -> forall (v :: * -> *) s a. Mutable v s a -> MRotcev v s a
MForward  forall a b. (a -> b) -> a -> b
$ forall (v :: * -> * -> *) a s.
MVector v a =>
Int -> Int -> v s a -> v s a
MV.basicUnsafeSlice Int
off Int
len Mutable v s a
v
    MBackward Mutable v s a
v -> forall (v :: * -> *) s a. Mutable v s a -> MRotcev v s a
MBackward forall a b. (a -> b) -> a -> b
$ forall (v :: * -> * -> *) a s.
MVector v a =>
Int -> Int -> v s a -> v s a
MV.basicUnsafeSlice (forall (v :: * -> * -> *) a s. MVector v a => v s a -> Int
MV.basicLength Mutable v s a
v forall a. Num a => a -> a -> a
- Int
off forall a. Num a => a -> a -> a
- Int
len) Int
len Mutable v s a
v
  basicOverlaps :: forall s. MRotcev v s a -> MRotcev v s a -> Bool
basicOverlaps = forall (v :: * -> * -> *) a s.
MVector v a =>
v s a -> v s a -> Bool
MV.basicOverlaps forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` forall (v :: * -> *) s a. MRotcev v s a -> Mutable v s a
fromMRotcev
  basicUnsafeNew :: forall s. Int -> ST s (MRotcev v s a)
basicUnsafeNew = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall (v :: * -> *) s a. Mutable v s a -> MRotcev v s a
MForward forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (v :: * -> * -> *) a s. MVector v a => Int -> ST s (v s a)
MV.basicUnsafeNew
  basicInitialize :: forall s. MRotcev v s a -> ST s ()
basicInitialize = forall (v :: * -> * -> *) a s. MVector v a => v s a -> ST s ()
MV.basicInitialize forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (v :: * -> *) s a. MRotcev v s a -> Mutable v s a
fromMRotcev
  basicUnsafeReplicate :: forall s. Int -> a -> ST s (MRotcev v s a)
basicUnsafeReplicate = (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall (v :: * -> *) s a. Mutable v s a -> MRotcev v s a
MForward forall b c a. (b -> c) -> (a -> b) -> a -> c
.) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (v :: * -> * -> *) a s.
MVector v a =>
Int -> a -> ST s (v s a)
MV.basicUnsafeReplicate
  basicUnsafeRead :: forall s. MRotcev v s a -> Int -> ST s a
basicUnsafeRead = \case
    MForward  Mutable v s a
v -> forall (v :: * -> * -> *) a s.
MVector v a =>
v s a -> Int -> ST s a
MV.basicUnsafeRead Mutable v s a
v
    MBackward Mutable v s a
v -> forall (v :: * -> * -> *) a s.
MVector v a =>
v s a -> Int -> ST s a
MV.basicUnsafeRead Mutable v s a
v forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((forall (v :: * -> * -> *) a s. MVector v a => v s a -> Int
MV.basicLength Mutable v s a
v forall a. Num a => a -> a -> a
- Int
1) forall a. Num a => a -> a -> a
-)
  basicUnsafeWrite :: forall s. MRotcev v s a -> Int -> a -> ST s ()
basicUnsafeWrite = \case
    MForward  Mutable v s a
v -> forall (v :: * -> * -> *) a s.
MVector v a =>
v s a -> Int -> a -> ST s ()
MV.basicUnsafeWrite Mutable v s a
v
    MBackward Mutable v s a
v -> forall (v :: * -> * -> *) a s.
MVector v a =>
v s a -> Int -> a -> ST s ()
MV.basicUnsafeWrite Mutable v s a
v forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((forall (v :: * -> * -> *) a s. MVector v a => v s a -> Int
MV.basicLength Mutable v s a
v forall a. Num a => a -> a -> a
- Int
1) forall a. Num a => a -> a -> a
-)
  basicClear :: forall s. MRotcev v s a -> ST s ()
basicClear = forall (v :: * -> * -> *) a s. MVector v a => v s a -> ST s ()
MV.basicClear forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (v :: * -> *) s a. MRotcev v s a -> Mutable v s a
fromMRotcev
  basicSet :: forall s. MRotcev v s a -> a -> ST s ()
basicSet = forall (v :: * -> * -> *) a s. MVector v a => v s a -> a -> ST s ()
MV.basicSet forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (v :: * -> *) s a. MRotcev v s a -> Mutable v s a
fromMRotcev

  basicUnsafeCopy :: forall s. MRotcev v s a -> MRotcev v s a -> ST s ()
basicUnsafeCopy !MRotcev v s a
dst' !MRotcev v s a
src' = case MRotcev v s a
dst' of
    MForward{} -> case MRotcev v s a
src' of
      MForward{}  -> forall (v :: * -> * -> *) a s.
MVector v a =>
v s a -> v s a -> ST s ()
MV.basicUnsafeCopy Mutable v s a
dst Mutable v s a
src
      MBackward{} -> Int -> ST s ()
do_copy Int
0
    MBackward{} -> case MRotcev v s a
src' of
      MForward{}  -> Int -> ST s ()
do_copy Int
0
      MBackward{} -> forall (v :: * -> * -> *) a s.
MVector v a =>
v s a -> v s a -> ST s ()
MV.basicUnsafeCopy Mutable v s a
dst Mutable v s a
src
    where
      dst :: Mutable v s a
dst = forall (v :: * -> *) s a. MRotcev v s a -> Mutable v s a
fromMRotcev MRotcev v s a
dst'
      src :: Mutable v s a
src = forall (v :: * -> *) s a. MRotcev v s a -> Mutable v s a
fromMRotcev MRotcev v s a
src'
      !n :: Int
n = forall (v :: * -> * -> *) a s. MVector v a => v s a -> Int
MV.basicLength Mutable v s a
src
      do_copy :: Int -> ST s ()
do_copy Int
i
        | Int
i forall a. Ord a => a -> a -> Bool
< Int
n = do
          a
x <- forall (v :: * -> * -> *) a s.
MVector v a =>
v s a -> Int -> ST s a
MV.basicUnsafeRead Mutable v s a
src Int
i
          forall (v :: * -> * -> *) a s.
MVector v a =>
v s a -> Int -> a -> ST s ()
MV.basicUnsafeWrite Mutable v s a
dst (Int
n forall a. Num a => a -> a -> a
- Int
1 forall a. Num a => a -> a -> a
- Int
i) a
x
          Int -> ST s ()
do_copy (Int
i forall a. Num a => a -> a -> a
+ Int
1)
        | Bool
otherwise = forall (f :: * -> *) a. Applicative f => a -> f a
pure ()

  basicUnsafeMove :: forall s. MRotcev v s a -> MRotcev v s a -> ST s ()
basicUnsafeMove !MRotcev v s a
dst !MRotcev v s a
src
    | forall (v :: * -> * -> *) a s.
MVector v a =>
v s a -> v s a -> Bool
MV.basicOverlaps MRotcev v s a
dst MRotcev v s a
src = do
      Mutable v s a
srcCopy' <- forall (v :: * -> * -> *) a s. MVector v a => Int -> ST s (v s a)
MV.basicUnsafeNew (forall (v :: * -> * -> *) a s. MVector v a => v s a -> Int
MV.basicLength MRotcev v s a
src)
      let srcCopy :: MRotcev v s a
srcCopy = case MRotcev v s a
dst of
            MForward{}  -> forall (v :: * -> *) s a. Mutable v s a -> MRotcev v s a
MForward Mutable v s a
srcCopy'
            MBackward{} -> case MRotcev v s a
src of
              MForward{}  -> forall (v :: * -> *) s a. Mutable v s a -> MRotcev v s a
MForward Mutable v s a
srcCopy'
              MBackward{} -> forall (v :: * -> *) s a. Mutable v s a -> MRotcev v s a
MBackward Mutable v s a
srcCopy'
      forall (v :: * -> * -> *) a s.
MVector v a =>
v s a -> v s a -> ST s ()
MV.basicUnsafeCopy MRotcev v s a
srcCopy MRotcev v s a
src
      forall (v :: * -> * -> *) a s.
MVector v a =>
v s a -> v s a -> ST s ()
MV.basicUnsafeCopy MRotcev v s a
dst MRotcev v s a
srcCopy
    | Bool
otherwise = forall (v :: * -> * -> *) a s.
MVector v a =>
v s a -> v s a -> ST s ()
MV.basicUnsafeCopy MRotcev v s a
dst MRotcev v s a
src

  basicUnsafeGrow :: forall s. MRotcev v s a -> Int -> ST s (MRotcev v s a)
basicUnsafeGrow (MForward Mutable v s a
v) Int
by = do
    let n :: Int
n = forall (v :: * -> * -> *) a s. MVector v a => v s a -> Int
MV.basicLength Mutable v s a
v
    Mutable v s a
v' <- forall (v :: * -> * -> *) a s. MVector v a => Int -> ST s (v s a)
MV.basicUnsafeNew (Int
n forall a. Num a => a -> a -> a
+ Int
by)
    forall (v :: * -> * -> *) a s.
MVector v a =>
v s a -> v s a -> ST s ()
MV.basicUnsafeCopy (forall (v :: * -> * -> *) a s.
MVector v a =>
Int -> Int -> v s a -> v s a
MV.basicUnsafeSlice Int
0 Int
n Mutable v s a
v') Mutable v s a
v
    forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall (v :: * -> *) s a. Mutable v s a -> MRotcev v s a
MForward Mutable v s a
v'
  basicUnsafeGrow (MBackward Mutable v s a
v) Int
by = do
    let n :: Int
n = forall (v :: * -> * -> *) a s. MVector v a => v s a -> Int
MV.basicLength Mutable v s a
v
    Mutable v s a
v' <- forall (v :: * -> * -> *) a s. MVector v a => Int -> ST s (v s a)
MV.basicUnsafeNew (Int
n forall a. Num a => a -> a -> a
+ Int
by)
    forall (v :: * -> * -> *) a s.
MVector v a =>
v s a -> v s a -> ST s ()
MV.basicUnsafeCopy (forall (v :: * -> * -> *) a s.
MVector v a =>
Int -> Int -> v s a -> v s a
MV.basicUnsafeSlice Int
by Int
n Mutable v s a
v') Mutable v s a
v
    forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall (v :: * -> *) s a. Mutable v s a -> MRotcev v s a
MBackward Mutable v s a
v'

  {-# INLINE basicLength           #-}
  {-# INLINE basicUnsafeSlice      #-}
  {-# INLINE basicOverlaps         #-}
  {-# INLINE basicUnsafeNew        #-}
  {-# INLINE basicInitialize       #-}
  {-# INLINE basicUnsafeReplicate  #-}
  {-# INLINE basicUnsafeRead       #-}
  {-# INLINE basicUnsafeWrite      #-}
  {-# INLINE basicUnsafeCopy       #-}
  {-# INLINE basicUnsafeMove       #-}
  {-# INLINE basicUnsafeGrow       #-}

instance V.Vector v a => V.Vector (Rotcev v) a where
  basicUnsafeFreeze :: forall s. Mutable (Rotcev v) s a -> ST s (Rotcev v a)
basicUnsafeFreeze = \case
    MForward  Mutable v s a
v -> forall (v :: * -> *) a. v a -> Rotcev v a
Forward  forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (v :: * -> *) a s. Vector v a => Mutable v s a -> ST s (v a)
V.basicUnsafeFreeze Mutable v s a
v
    MBackward Mutable v s a
v -> forall (v :: * -> *) a. v a -> Rotcev v a
Backward forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (v :: * -> *) a s. Vector v a => Mutable v s a -> ST s (v a)
V.basicUnsafeFreeze Mutable v s a
v
  basicUnsafeThaw :: forall s. Rotcev v a -> ST s (Mutable (Rotcev v) s a)
basicUnsafeThaw = \case
    Forward  v a
v -> forall (v :: * -> *) s a. Mutable v s a -> MRotcev v s a
MForward  forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (v :: * -> *) a s. Vector v a => v a -> ST s (Mutable v s a)
V.basicUnsafeThaw v a
v
    Backward v a
v -> forall (v :: * -> *) s a. Mutable v s a -> MRotcev v s a
MBackward forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (v :: * -> *) a s. Vector v a => v a -> ST s (Mutable v s a)
V.basicUnsafeThaw v a
v
  basicLength :: Rotcev v a -> Int
basicLength = forall (v :: * -> *) a. Vector v a => v a -> Int
V.basicLength forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (v :: * -> *) a. Rotcev v a -> v a
fromRotcev
  basicUnsafeSlice :: Int -> Int -> Rotcev v a -> Rotcev v a
basicUnsafeSlice Int
off Int
len = \case
    Forward  v a
v -> forall (v :: * -> *) a. v a -> Rotcev v a
Forward  forall a b. (a -> b) -> a -> b
$ forall (v :: * -> *) a. Vector v a => Int -> Int -> v a -> v a
V.basicUnsafeSlice Int
off Int
len v a
v
    Backward v a
v -> forall (v :: * -> *) a. v a -> Rotcev v a
Backward forall a b. (a -> b) -> a -> b
$ forall (v :: * -> *) a. Vector v a => Int -> Int -> v a -> v a
V.basicUnsafeSlice (forall (v :: * -> *) a. Vector v a => v a -> Int
V.basicLength v a
v forall a. Num a => a -> a -> a
- Int
off forall a. Num a => a -> a -> a
- Int
len) Int
len v a
v
  basicUnsafeIndexM :: Rotcev v a -> Int -> Box a
basicUnsafeIndexM = \case
    Forward  v a
v -> forall (v :: * -> *) a. Vector v a => v a -> Int -> Box a
V.basicUnsafeIndexM v a
v
    Backward v a
v -> forall (v :: * -> *) a. Vector v a => v a -> Int -> Box a
V.basicUnsafeIndexM v a
v forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((forall (v :: * -> *) a. Vector v a => v a -> Int
V.basicLength v a
v forall a. Num a => a -> a -> a
- Int
1) forall a. Num a => a -> a -> a
-)

  basicUnsafeCopy :: forall s. Mutable (Rotcev v) s a -> Rotcev v a -> ST s ()
basicUnsafeCopy !Mutable (Rotcev v) s a
dst' !Rotcev v a
src' = case Mutable (Rotcev v) s a
dst' of
    MForward{} -> case Rotcev v a
src' of
      Forward{}  -> forall (v :: * -> *) a s.
Vector v a =>
Mutable v s a -> v a -> ST s ()
V.basicUnsafeCopy Mutable v s a
dst v a
src
      Backward{} -> Int -> ST s ()
do_copy Int
0
    MBackward{} -> case Rotcev v a
src' of
      Forward{}  -> Int -> ST s ()
do_copy Int
0
      Backward{} -> forall (v :: * -> *) a s.
Vector v a =>
Mutable v s a -> v a -> ST s ()
V.basicUnsafeCopy Mutable v s a
dst v a
src
    where
      dst :: Mutable v s a
dst = forall (v :: * -> *) s a. MRotcev v s a -> Mutable v s a
fromMRotcev Mutable (Rotcev v) s a
dst'
      src :: v a
src = forall (v :: * -> *) a. Rotcev v a -> v a
fromRotcev  Rotcev v a
src'
      !n :: Int
n = forall (v :: * -> *) a. Vector v a => v a -> Int
V.basicLength v a
src

      do_copy :: Int -> ST s ()
do_copy Int
i
        | Int
i forall a. Ord a => a -> a -> Bool
< Int
n = case forall (v :: * -> *) a. Vector v a => v a -> Int -> Box a
V.basicUnsafeIndexM v a
src Int
i of
          Box a
x -> do
            forall (v :: * -> * -> *) a s.
MVector v a =>
v s a -> Int -> a -> ST s ()
MV.basicUnsafeWrite Mutable v s a
dst (Int
n forall a. Num a => a -> a -> a
- Int
1 forall a. Num a => a -> a -> a
- Int
i) a
x
            Int -> ST s ()
do_copy (Int
i forall a. Num a => a -> a -> a
+ Int
1)
        | Bool
otherwise = forall (f :: * -> *) a. Applicative f => a -> f a
pure ()

  {-# INLINE basicUnsafeFreeze #-}
  {-# INLINE basicUnsafeThaw   #-}
  {-# INLINE basicLength       #-}
  {-# INLINE basicUnsafeSlice  #-}
  {-# INLINE basicUnsafeIndexM #-}
  {-# INLINE basicUnsafeCopy   #-}