{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# OPTIONS_GHC -Wall #-}
{-# OPTIONS_HADDOCK show-extensions #-}
-----------------------------------------------------------------------------
-- |
-- Module      :  ToySolver.Internal.Data.Vec
-- Copyright   :  (c) Masahiro Sakai 2014
-- License     :  BSD-style
--
-- Maintainer  :  masahiro.sakai@gmail.com
-- Stability   :  provisional
-- Portability :  non-portable
--
-- Simple 1-dimentional resizable array
--
-----------------------------------------------------------------------------
module ToySolver.Internal.Data.Vec
  (
  -- * Vec type
    GenericVec
  , Vec
  , UVec
  , Index

  -- * Constructors
  , new
  , clone

  -- * Operators
  , getSize
  , read
  , write
  , modify
  , modify'
  , unsafeRead
  , unsafeWrite
  , unsafeModify
  , unsafeModify'
  , resize
  , growTo
  , push
  , pop
  , popMaybe
  , unsafePop
  , peek
  , unsafePeek
  , clear
  , getElems

  -- * Low-level operators
  , getArray
  , getCapacity
  , resizeCapacity
  ) where

import Prelude hiding (read)

import Control.Loop
import Control.Monad
import Data.Ix
import qualified Data.Array.Base as A
import qualified Data.Array.IO as A
import Data.IORef
import ToySolver.Internal.Data.IOURef

data GenericVec a e = GenericVec {-# UNPACK #-} !(IOURef Int) {-# UNPACK #-} !(IORef (a Index e))
  deriving GenericVec a e -> GenericVec a e -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall (a :: * -> * -> *) e.
GenericVec a e -> GenericVec a e -> Bool
/= :: GenericVec a e -> GenericVec a e -> Bool
$c/= :: forall (a :: * -> * -> *) e.
GenericVec a e -> GenericVec a e -> Bool
== :: GenericVec a e -> GenericVec a e -> Bool
$c== :: forall (a :: * -> * -> *) e.
GenericVec a e -> GenericVec a e -> Bool
Eq

type Vec e = GenericVec A.IOArray e
type UVec e = GenericVec A.IOUArray e

type Index = Int

{- INLINE readArray #-}
readArray :: A.MArray a e m => a Index e -> Index -> m e
#ifdef EXTRA_BOUNDS_CHECKING
readArray = A.readArray
#else
readArray :: forall (a :: * -> * -> *) e (m :: * -> *).
MArray a e m =>
a Int e -> Int -> m e
readArray = forall (a :: * -> * -> *) e (m :: * -> *) i.
(MArray a e m, Ix i) =>
a i e -> Int -> m e
A.unsafeRead
#endif

{- INLINE writeArray #-}
writeArray :: A.MArray a e m => a Index e -> Index -> e -> m ()
#ifdef EXTRA_BOUNDS_CHECKING
writeArray = A.writeArray
#else
writeArray :: forall (a :: * -> * -> *) e (m :: * -> *).
MArray a e m =>
a Int e -> Int -> e -> m ()
writeArray = forall (a :: * -> * -> *) e (m :: * -> *) i.
(MArray a e m, Ix i) =>
a i e -> Int -> e -> m ()
A.unsafeWrite
#endif

new :: A.MArray a e IO => IO (GenericVec a e)
new :: forall (a :: * -> * -> *) e. MArray a e IO => IO (GenericVec a e)
new = do
  IOURef Int
sizeRef <- forall a. MArray IOUArray a IO => a -> IO (IOURef a)
newIOURef Int
0
  IORef (a Int e)
arrayRef <- forall a. a -> IO (IORef a)
newIORef forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall (a :: * -> * -> *) e (m :: * -> *) i.
(MArray a e m, Ix i) =>
(i, i) -> m (a i e)
A.newArray_ (Int
0,-Int
1)
  forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall (a :: * -> * -> *) e.
IOURef Int -> IORef (a Int e) -> GenericVec a e
GenericVec IOURef Int
sizeRef IORef (a Int e)
arrayRef

{- INLINE getSize #-}
-- | Get the internal representation array
getSize :: GenericVec a e -> IO Int
getSize :: forall (a :: * -> * -> *) e. GenericVec a e -> IO Int
getSize (GenericVec IOURef Int
sizeRef IORef (a Int e)
_) = forall a. MArray IOUArray a IO => IOURef a -> IO a
readIOURef IOURef Int
sizeRef

{-# SPECIALIZE read :: Vec e -> Int -> IO e #-}
{-# SPECIALIZE read :: UVec Int -> Int -> IO Int #-}
{-# SPECIALIZE read :: UVec Double -> Int -> IO Double #-}
{-# SPECIALIZE read :: UVec Bool -> Int -> IO Bool #-}
read :: A.MArray a e IO => GenericVec a e -> Int -> IO e
read :: forall (a :: * -> * -> *) e.
MArray a e IO =>
GenericVec a e -> Int -> IO e
read !GenericVec a e
v !Int
i = do
  a Int e
a <- forall (a :: * -> * -> *) e. GenericVec a e -> IO (a Int e)
getArray GenericVec a e
v
  Int
s <- forall (a :: * -> * -> *) e. GenericVec a e -> IO Int
getSize GenericVec a e
v
  if Int
0 forall a. Ord a => a -> a -> Bool
<= Int
i Bool -> Bool -> Bool
&& Int
i forall a. Ord a => a -> a -> Bool
< Int
s then
    forall (a :: * -> * -> *) e (m :: * -> *).
MArray a e m =>
a Int e -> Int -> m e
readArray a Int e
a Int
i
  else
    forall a. HasCallStack => [Char] -> a
error forall a b. (a -> b) -> a -> b
$ [Char]
"ToySolver.Internal.Data.Vec.read: index " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Int
i forall a. [a] -> [a] -> [a]
++ [Char]
" out of bounds"

{-# SPECIALIZE write :: Vec e -> Int -> e -> IO () #-}
{-# SPECIALIZE write :: UVec Int -> Int -> Int -> IO () #-}
{-# SPECIALIZE write :: UVec Double -> Int -> Double -> IO () #-}
{-# SPECIALIZE write :: UVec Bool -> Int -> Bool -> IO () #-}
write :: A.MArray a e IO => GenericVec a e -> Int -> e -> IO ()
write :: forall (a :: * -> * -> *) e.
MArray a e IO =>
GenericVec a e -> Int -> e -> IO ()
write !GenericVec a e
v !Int
i e
e = do
  a Int e
a <- forall (a :: * -> * -> *) e. GenericVec a e -> IO (a Int e)
getArray GenericVec a e
v
  Int
s <- forall (a :: * -> * -> *) e. GenericVec a e -> IO Int
getSize GenericVec a e
v
  if Int
0 forall a. Ord a => a -> a -> Bool
<= Int
i Bool -> Bool -> Bool
&& Int
i forall a. Ord a => a -> a -> Bool
< Int
s then
    forall (a :: * -> * -> *) e (m :: * -> *).
MArray a e m =>
a Int e -> Int -> e -> m ()
writeArray a Int e
a Int
i e
e
  else
    forall a. HasCallStack => [Char] -> a
error forall a b. (a -> b) -> a -> b
$ [Char]
"ToySolver.Internal.Data.Vec.write: index " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Int
i forall a. [a] -> [a] -> [a]
++ [Char]
" out of bounds"

{-# INLINE modify #-}
modify :: A.MArray a e IO => GenericVec a e -> Int -> (e -> e) -> IO ()
modify :: forall (a :: * -> * -> *) e.
MArray a e IO =>
GenericVec a e -> Int -> (e -> e) -> IO ()
modify !GenericVec a e
v !Int
i e -> e
f = do
  a Int e
a <- forall (a :: * -> * -> *) e. GenericVec a e -> IO (a Int e)
getArray GenericVec a e
v
  Int
s <- forall (a :: * -> * -> *) e. GenericVec a e -> IO Int
getSize GenericVec a e
v
  if Int
0 forall a. Ord a => a -> a -> Bool
<= Int
i Bool -> Bool -> Bool
&& Int
i forall a. Ord a => a -> a -> Bool
< Int
s then do
    e
x <- forall (a :: * -> * -> *) e (m :: * -> *).
MArray a e m =>
a Int e -> Int -> m e
readArray a Int e
a Int
i
    forall (a :: * -> * -> *) e (m :: * -> *).
MArray a e m =>
a Int e -> Int -> e -> m ()
writeArray a Int e
a Int
i (e -> e
f e
x)
  else
    forall a. HasCallStack => [Char] -> a
error forall a b. (a -> b) -> a -> b
$ [Char]
"ToySolver.Internal.Data.Vec.modify: index " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Int
i forall a. [a] -> [a] -> [a]
++ [Char]
" out of bounds"

{-# INLINE modify' #-}
modify' :: A.MArray a e IO => GenericVec a e -> Int -> (e -> e) -> IO ()
modify' :: forall (a :: * -> * -> *) e.
MArray a e IO =>
GenericVec a e -> Int -> (e -> e) -> IO ()
modify' !GenericVec a e
v !Int
i e -> e
f = do
  a Int e
a <- forall (a :: * -> * -> *) e. GenericVec a e -> IO (a Int e)
getArray GenericVec a e
v
  Int
s <- forall (a :: * -> * -> *) e. GenericVec a e -> IO Int
getSize GenericVec a e
v
  if Int
0 forall a. Ord a => a -> a -> Bool
<= Int
i Bool -> Bool -> Bool
&& Int
i forall a. Ord a => a -> a -> Bool
< Int
s then do
    e
x <- forall (a :: * -> * -> *) e (m :: * -> *).
MArray a e m =>
a Int e -> Int -> m e
readArray a Int e
a Int
i
    forall (a :: * -> * -> *) e (m :: * -> *).
MArray a e m =>
a Int e -> Int -> e -> m ()
writeArray a Int e
a Int
i forall a b. (a -> b) -> a -> b
$! e -> e
f e
x
  else
    forall a. HasCallStack => [Char] -> a
error forall a b. (a -> b) -> a -> b
$ [Char]
"ToySolver.Internal.Data.Vec.modify': index " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Int
i forall a. [a] -> [a] -> [a]
++ [Char]
" out of bounds"

{-# INLINE unsafeModify #-}
unsafeModify :: A.MArray a e IO => GenericVec a e -> Int -> (e -> e) -> IO ()
unsafeModify :: forall (a :: * -> * -> *) e.
MArray a e IO =>
GenericVec a e -> Int -> (e -> e) -> IO ()
unsafeModify !GenericVec a e
v !Int
i e -> e
f = do
  a Int e
a <- forall (a :: * -> * -> *) e. GenericVec a e -> IO (a Int e)
getArray GenericVec a e
v
  e
x <- forall (a :: * -> * -> *) e (m :: * -> *).
MArray a e m =>
a Int e -> Int -> m e
readArray a Int e
a Int
i
  forall (a :: * -> * -> *) e (m :: * -> *).
MArray a e m =>
a Int e -> Int -> e -> m ()
writeArray a Int e
a Int
i (e -> e
f e
x)

{-# INLINE unsafeModify' #-}
unsafeModify' :: A.MArray a e IO => GenericVec a e -> Int -> (e -> e) -> IO ()
unsafeModify' :: forall (a :: * -> * -> *) e.
MArray a e IO =>
GenericVec a e -> Int -> (e -> e) -> IO ()
unsafeModify' !GenericVec a e
v !Int
i e -> e
f = do
  a Int e
a <- forall (a :: * -> * -> *) e. GenericVec a e -> IO (a Int e)
getArray GenericVec a e
v
  e
x <- forall (a :: * -> * -> *) e (m :: * -> *).
MArray a e m =>
a Int e -> Int -> m e
readArray a Int e
a Int
i
  forall (a :: * -> * -> *) e (m :: * -> *).
MArray a e m =>
a Int e -> Int -> e -> m ()
writeArray a Int e
a Int
i forall a b. (a -> b) -> a -> b
$! e -> e
f e
x

{-# INLINE unsafeRead #-}
unsafeRead :: A.MArray a e IO => GenericVec a e -> Int -> IO e
unsafeRead :: forall (a :: * -> * -> *) e.
MArray a e IO =>
GenericVec a e -> Int -> IO e
unsafeRead !GenericVec a e
v !Int
i = do
  a Int e
a <- forall (a :: * -> * -> *) e. GenericVec a e -> IO (a Int e)
getArray GenericVec a e
v
  forall (a :: * -> * -> *) e (m :: * -> *).
MArray a e m =>
a Int e -> Int -> m e
readArray a Int e
a Int
i

{-# INLINE unsafeWrite #-}
unsafeWrite :: A.MArray a e IO => GenericVec a e -> Int -> e -> IO ()
unsafeWrite :: forall (a :: * -> * -> *) e.
MArray a e IO =>
GenericVec a e -> Int -> e -> IO ()
unsafeWrite !GenericVec a e
v !Int
i e
e = do
  a Int e
a <- forall (a :: * -> * -> *) e. GenericVec a e -> IO (a Int e)
getArray GenericVec a e
v
  forall (a :: * -> * -> *) e (m :: * -> *).
MArray a e m =>
a Int e -> Int -> e -> m ()
writeArray a Int e
a Int
i e
e

{-# SPECIALIZE resize :: Vec e -> Int -> IO () #-}
{-# SPECIALIZE resize :: UVec Int -> Int -> IO () #-}
{-# SPECIALIZE resize :: UVec Double -> Int -> IO () #-}
{-# SPECIALIZE resize :: UVec Bool -> Int -> IO () #-}
resize :: A.MArray a e IO => GenericVec a e -> Int -> IO ()
resize :: forall (a :: * -> * -> *) e.
MArray a e IO =>
GenericVec a e -> Int -> IO ()
resize v :: GenericVec a e
v@(GenericVec IOURef Int
sizeRef IORef (a Int e)
arrayRef) !Int
n = do
  a Int e
a <- forall (a :: * -> * -> *) e. GenericVec a e -> IO (a Int e)
getArray GenericVec a e
v
  Int
capa <- forall (a :: * -> * -> *) e.
MArray a e IO =>
GenericVec a e -> IO Int
getCapacity GenericVec a e
v
  forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (Int
n forall a. Ord a => a -> a -> Bool
<= Int
capa) forall a b. (a -> b) -> a -> b
$ do
    let capa' :: Int
capa' = forall a. Ord a => a -> a -> a
max Int
2 (Int
capa forall a. Num a => a -> a -> a
* Int
3 forall a. Integral a => a -> a -> a
`div` Int
2)
    a Int e
a' <- forall (a :: * -> * -> *) e (m :: * -> *) i.
(MArray a e m, Ix i) =>
(i, i) -> m (a i e)
A.newArray_ (Int
0, Int
capa'forall a. Num a => a -> a -> a
-Int
1)
    forall (a :: * -> * -> *) e (m :: * -> *).
MArray a e m =>
a Int e -> a Int e -> (Int, Int) -> m ()
copyTo a Int e
a a Int e
a' (Int
0,Int
capaforall a. Num a => a -> a -> a
-Int
1)
    forall a. IORef a -> a -> IO ()
writeIORef IORef (a Int e)
arrayRef a Int e
a'
  forall a. MArray IOUArray a IO => IOURef a -> a -> IO ()
writeIOURef IOURef Int
sizeRef Int
n

{-# SPECIALIZE growTo :: Vec e -> Int -> IO () #-}
{-# SPECIALIZE growTo :: UVec Int -> Int -> IO () #-}
{-# SPECIALIZE growTo :: UVec Double -> Int -> IO () #-}
{-# SPECIALIZE growTo :: UVec Bool -> Int -> IO () #-}
growTo :: A.MArray a e IO => GenericVec a e -> Int -> IO ()
growTo :: forall (a :: * -> * -> *) e.
MArray a e IO =>
GenericVec a e -> Int -> IO ()
growTo GenericVec a e
v !Int
n = do
  Int
m <- forall (a :: * -> * -> *) e. GenericVec a e -> IO Int
getSize GenericVec a e
v
  forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Int
m forall a. Ord a => a -> a -> Bool
< Int
n) forall a b. (a -> b) -> a -> b
$ forall (a :: * -> * -> *) e.
MArray a e IO =>
GenericVec a e -> Int -> IO ()
resize GenericVec a e
v Int
n

{-# SPECIALIZE push :: Vec e -> e -> IO () #-}
{-# SPECIALIZE push :: UVec Int -> Int -> IO () #-}
{-# SPECIALIZE push :: UVec Double -> Double -> IO () #-}
{-# SPECIALIZE push :: UVec Bool -> Bool -> IO () #-}
push :: A.MArray a e IO => GenericVec a e -> e -> IO ()
push :: forall (a :: * -> * -> *) e.
MArray a e IO =>
GenericVec a e -> e -> IO ()
push GenericVec a e
v e
e = do
  Int
s <- forall (a :: * -> * -> *) e. GenericVec a e -> IO Int
getSize GenericVec a e
v
  forall (a :: * -> * -> *) e.
MArray a e IO =>
GenericVec a e -> Int -> IO ()
resize GenericVec a e
v (Int
sforall a. Num a => a -> a -> a
+Int
1)
  forall (a :: * -> * -> *) e.
MArray a e IO =>
GenericVec a e -> Int -> e -> IO ()
unsafeWrite GenericVec a e
v Int
s e
e

popMaybe :: A.MArray a e IO => GenericVec a e -> IO (Maybe e)
popMaybe :: forall (a :: * -> * -> *) e.
MArray a e IO =>
GenericVec a e -> IO (Maybe e)
popMaybe GenericVec a e
v = do
  Int
s <- forall (a :: * -> * -> *) e. GenericVec a e -> IO Int
getSize GenericVec a e
v
  if Int
s forall a. Eq a => a -> a -> Bool
== Int
0 then
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
  else do
    e
e <- forall (a :: * -> * -> *) e.
MArray a e IO =>
GenericVec a e -> Int -> IO e
unsafeRead GenericVec a e
v (Int
sforall a. Num a => a -> a -> a
-Int
1)
    forall (a :: * -> * -> *) e.
MArray a e IO =>
GenericVec a e -> Int -> IO ()
resize GenericVec a e
v (Int
sforall a. Num a => a -> a -> a
-Int
1)
    forall (m :: * -> *) a. Monad m => a -> m a
return (forall a. a -> Maybe a
Just e
e)

{-# SPECIALIZE unsafePop :: Vec e -> IO e #-}
{-# SPECIALIZE unsafePop :: UVec Int -> IO Int #-}
{-# SPECIALIZE unsafePop :: UVec Double -> IO Double #-}
{-# SPECIALIZE unsafePop :: UVec Bool -> IO Bool #-}
pop :: A.MArray a e IO => GenericVec a e -> IO e
pop :: forall (a :: * -> * -> *) e.
MArray a e IO =>
GenericVec a e -> IO e
pop GenericVec a e
v = do
  Int
s <- forall (a :: * -> * -> *) e. GenericVec a e -> IO Int
getSize GenericVec a e
v
  if Int
s forall a. Eq a => a -> a -> Bool
== Int
0 then
    forall a. HasCallStack => [Char] -> a
error forall a b. (a -> b) -> a -> b
$ [Char]
"ToySolver.Internal.Data.Vec.pop: empty Vec"
  else do
    e
e <- forall (a :: * -> * -> *) e.
MArray a e IO =>
GenericVec a e -> Int -> IO e
unsafeRead GenericVec a e
v (Int
sforall a. Num a => a -> a -> a
-Int
1)
    forall (a :: * -> * -> *) e.
MArray a e IO =>
GenericVec a e -> Int -> IO ()
resize GenericVec a e
v (Int
sforall a. Num a => a -> a -> a
-Int
1)
    forall (m :: * -> *) a. Monad m => a -> m a
return e
e

{-# SPECIALIZE unsafePop :: Vec e -> IO e #-}
{-# SPECIALIZE unsafePop :: UVec Int -> IO Int #-}
{-# SPECIALIZE unsafePop :: UVec Double -> IO Double #-}
{-# SPECIALIZE unsafePop :: UVec Bool -> IO Bool #-}
unsafePop :: A.MArray a e IO => GenericVec a e -> IO e
unsafePop :: forall (a :: * -> * -> *) e.
MArray a e IO =>
GenericVec a e -> IO e
unsafePop GenericVec a e
v = do
  Int
s <- forall (a :: * -> * -> *) e. GenericVec a e -> IO Int
getSize GenericVec a e
v
  e
e <- forall (a :: * -> * -> *) e.
MArray a e IO =>
GenericVec a e -> Int -> IO e
unsafeRead GenericVec a e
v (Int
sforall a. Num a => a -> a -> a
-Int
1)
  forall (a :: * -> * -> *) e.
MArray a e IO =>
GenericVec a e -> Int -> IO ()
resize GenericVec a e
v (Int
sforall a. Num a => a -> a -> a
-Int
1)
  forall (m :: * -> *) a. Monad m => a -> m a
return e
e

{-# INLINE peek #-}
peek :: A.MArray a e IO => GenericVec a e -> IO e
peek :: forall (a :: * -> * -> *) e.
MArray a e IO =>
GenericVec a e -> IO e
peek GenericVec a e
v = do
  Int
s <- forall (a :: * -> * -> *) e. GenericVec a e -> IO Int
getSize GenericVec a e
v
  if Int
s forall a. Eq a => a -> a -> Bool
== Int
0 then
    forall a. HasCallStack => [Char] -> a
error forall a b. (a -> b) -> a -> b
$ [Char]
"ToySolver.Internal.Data.Vec.peek: empty Vec"
  else do
    forall (a :: * -> * -> *) e.
MArray a e IO =>
GenericVec a e -> Int -> IO e
unsafeRead GenericVec a e
v (Int
sforall a. Num a => a -> a -> a
-Int
1)

{-# INLINE unsafePeek #-}
unsafePeek :: A.MArray a e IO => GenericVec a e -> IO e
unsafePeek :: forall (a :: * -> * -> *) e.
MArray a e IO =>
GenericVec a e -> IO e
unsafePeek GenericVec a e
v = do
  Int
s <- forall (a :: * -> * -> *) e. GenericVec a e -> IO Int
getSize GenericVec a e
v
  forall (a :: * -> * -> *) e.
MArray a e IO =>
GenericVec a e -> Int -> IO e
unsafeRead GenericVec a e
v (Int
sforall a. Num a => a -> a -> a
-Int
1)

clear :: A.MArray a e IO => GenericVec a e -> IO ()
clear :: forall (a :: * -> * -> *) e.
MArray a e IO =>
GenericVec a e -> IO ()
clear GenericVec a e
v = forall (a :: * -> * -> *) e.
MArray a e IO =>
GenericVec a e -> Int -> IO ()
resize GenericVec a e
v Int
0

getElems :: A.MArray a e IO => GenericVec a e -> IO [e]
getElems :: forall (a :: * -> * -> *) e.
MArray a e IO =>
GenericVec a e -> IO [e]
getElems GenericVec a e
v = do
  Int
s <- forall (a :: * -> * -> *) e. GenericVec a e -> IO Int
getSize GenericVec a e
v
  forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM [Int
0..Int
sforall a. Num a => a -> a -> a
-Int
1] forall a b. (a -> b) -> a -> b
$ \Int
i -> forall (a :: * -> * -> *) e.
MArray a e IO =>
GenericVec a e -> Int -> IO e
unsafeRead GenericVec a e
v Int
i

{-# SPECIALIZE clone :: Vec e -> IO (Vec e) #-}
{-# SPECIALIZE clone :: UVec Int -> IO (UVec Int) #-}
{-# SPECIALIZE clone :: UVec Double -> IO (UVec Double) #-}
{-# SPECIALIZE clone :: UVec Bool -> IO (UVec Bool) #-}
clone :: A.MArray a e IO => GenericVec a e -> IO (GenericVec a e)
clone :: forall (a :: * -> * -> *) e.
MArray a e IO =>
GenericVec a e -> IO (GenericVec a e)
clone (GenericVec IOURef Int
sizeRef IORef (a Int e)
arrayRef) = do
  a Int e
a <- forall a. IORef a -> IO a
readIORef IORef (a Int e)
arrayRef
  IORef (a Int e)
arrayRef' <- forall a. a -> IO (IORef a)
newIORef forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall (a :: * -> * -> *) e (m :: * -> *).
MArray a e m =>
a Int e -> m (a Int e)
cloneArray a Int e
a
  IOURef Int
sizeRef'  <- forall a. MArray IOUArray a IO => a -> IO (IOURef a)
newIOURef forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall a. MArray IOUArray a IO => IOURef a -> IO a
readIOURef IOURef Int
sizeRef
  forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall (a :: * -> * -> *) e.
IOURef Int -> IORef (a Int e) -> GenericVec a e
GenericVec IOURef Int
sizeRef' IORef (a Int e)
arrayRef'

{--------------------------------------------------------------------

--------------------------------------------------------------------}

{-# INLINE getArray #-}
-- | Get the internal representation array
getArray :: GenericVec a e -> IO (a Index e)
getArray :: forall (a :: * -> * -> *) e. GenericVec a e -> IO (a Int e)
getArray (GenericVec IOURef Int
_ IORef (a Int e)
arrayRef) = forall a. IORef a -> IO a
readIORef IORef (a Int e)
arrayRef

{-# INLINE getCapacity #-}
-- | Get the internal representation array
getCapacity :: A.MArray a e IO => GenericVec a e -> IO Int
getCapacity :: forall (a :: * -> * -> *) e.
MArray a e IO =>
GenericVec a e -> IO Int
getCapacity GenericVec a e
vec = forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM forall a. Ix a => (a, a) -> Int
rangeSize forall a b. (a -> b) -> a -> b
$ forall (a :: * -> * -> *) e (m :: * -> *) i.
(MArray a e m, Ix i) =>
a i e -> m (i, i)
A.getBounds forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall (a :: * -> * -> *) e. GenericVec a e -> IO (a Int e)
getArray GenericVec a e
vec

{-# SPECIALIZE resizeCapacity :: Vec e -> Int -> IO () #-}
{-# SPECIALIZE resizeCapacity :: UVec Int -> Int -> IO () #-}
{-# SPECIALIZE resizeCapacity :: UVec Double -> Int -> IO () #-}
{-# SPECIALIZE resizeCapacity :: UVec Bool -> Int -> IO () #-}
-- | Pre-allocate internal buffer for @n@ elements.
resizeCapacity :: A.MArray a e IO => GenericVec a e -> Int -> IO ()
resizeCapacity :: forall (a :: * -> * -> *) e.
MArray a e IO =>
GenericVec a e -> Int -> IO ()
resizeCapacity (GenericVec IOURef Int
sizeRef IORef (a Int e)
arrayRef) Int
capa = do
  Int
n <- forall a. MArray IOUArray a IO => IOURef a -> IO a
readIOURef IOURef Int
sizeRef
  a Int e
arr <- forall a. IORef a -> IO a
readIORef IORef (a Int e)
arrayRef
  Int
capa0 <- forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM forall a. Ix a => (a, a) -> Int
rangeSize forall a b. (a -> b) -> a -> b
$ forall (a :: * -> * -> *) e (m :: * -> *) i.
(MArray a e m, Ix i) =>
a i e -> m (i, i)
A.getBounds a Int e
arr
  forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Int
capa0 forall a. Ord a => a -> a -> Bool
< Int
capa) forall a b. (a -> b) -> a -> b
$ do
    let capa' :: Int
capa' = forall a. Ord a => a -> a -> a
max Int
capa (Int
n forall a. Num a => a -> a -> a
* Int
3 forall a. Integral a => a -> a -> a
`div` Int
2)
    a Int e
arr' <- forall (a :: * -> * -> *) e (m :: * -> *) i.
(MArray a e m, Ix i) =>
(i, i) -> m (a i e)
A.newArray_ (Int
0, Int
capa'forall a. Num a => a -> a -> a
-Int
1)
    forall (a :: * -> * -> *) e (m :: * -> *).
MArray a e m =>
a Int e -> a Int e -> (Int, Int) -> m ()
copyTo a Int e
arr a Int e
arr' (Int
0, Int
nforall a. Num a => a -> a -> a
-Int
1)
    forall a. IORef a -> a -> IO ()
writeIORef IORef (a Int e)
arrayRef a Int e
arr'

{--------------------------------------------------------------------
  utility
--------------------------------------------------------------------}

{-# INLINE cloneArray #-}
cloneArray :: (A.MArray a e m) => a Index e -> m (a Index e)
cloneArray :: forall (a :: * -> * -> *) e (m :: * -> *).
MArray a e m =>
a Int e -> m (a Int e)
cloneArray a Int e
arr = do
  (Int, Int)
b <- forall (a :: * -> * -> *) e (m :: * -> *) i.
(MArray a e m, Ix i) =>
a i e -> m (i, i)
A.getBounds a Int e
arr
  a Int e
arr' <- forall (a :: * -> * -> *) e (m :: * -> *) i.
(MArray a e m, Ix i) =>
(i, i) -> m (a i e)
A.newArray_ (Int, Int)
b
  forall (a :: * -> * -> *) e (m :: * -> *).
MArray a e m =>
a Int e -> a Int e -> (Int, Int) -> m ()
copyTo a Int e
arr a Int e
arr' (Int, Int)
b
  forall (m :: * -> *) a. Monad m => a -> m a
return a Int e
arr'

{-# INLINE copyTo #-}
copyTo :: (A.MArray a e m) => a Index e -> a Index e -> (Index,Index) -> m ()
copyTo :: forall (a :: * -> * -> *) e (m :: * -> *).
MArray a e m =>
a Int e -> a Int e -> (Int, Int) -> m ()
copyTo a Int e
fromArr a Int e
toArr (!Int
lb,!Int
ub) = do
  forall (m :: * -> *) a.
Monad m =>
a -> (a -> Bool) -> (a -> a) -> (a -> m ()) -> m ()
forLoop Int
lb (forall a. Ord a => a -> a -> Bool
<=Int
ub) (forall a. Num a => a -> a -> a
+Int
1) forall a b. (a -> b) -> a -> b
$ \Int
i -> do
    e
val_i <- forall (a :: * -> * -> *) e (m :: * -> *).
MArray a e m =>
a Int e -> Int -> m e
readArray a Int e
fromArr Int
i
    forall (a :: * -> * -> *) e (m :: * -> *).
MArray a e m =>
a Int e -> Int -> e -> m ()
writeArray a Int e
toArr Int
i e
val_i