{-# 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
(GenericVec a e -> GenericVec a e -> Bool)
-> (GenericVec a e -> GenericVec a e -> Bool)
-> Eq (GenericVec a e)
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 :: a Index e -> Index -> m e
readArray = a Index e -> Index -> m e
forall (a :: * -> * -> *) e (m :: * -> *) i.
(MArray a e m, Ix i) =>
a i e -> Index -> 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 :: a Index e -> Index -> e -> m ()
writeArray = a Index e -> Index -> e -> m ()
forall (a :: * -> * -> *) e (m :: * -> *) i.
(MArray a e m, Ix i) =>
a i e -> Index -> e -> m ()
A.unsafeWrite
#endif

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

{- INLINE getSize #-}
-- | Get the internal representation array
getSize :: GenericVec a e -> IO Int
getSize :: GenericVec a e -> IO Index
getSize (GenericVec IOURef Index
sizeRef IORef (a Index e)
_) = IOURef Index -> IO Index
forall a. MArray IOUArray a IO => IOURef a -> IO a
readIOURef IOURef Index
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 :: GenericVec a e -> Index -> IO e
read !GenericVec a e
v !Index
i = do
  a Index e
a <- GenericVec a e -> IO (a Index e)
forall (a :: * -> * -> *) e. GenericVec a e -> IO (a Index e)
getArray GenericVec a e
v
  Index
s <- GenericVec a e -> IO Index
forall (a :: * -> * -> *) e. GenericVec a e -> IO Index
getSize GenericVec a e
v
  if Index
0 Index -> Index -> Bool
forall a. Ord a => a -> a -> Bool
<= Index
i Bool -> Bool -> Bool
&& Index
i Index -> Index -> Bool
forall a. Ord a => a -> a -> Bool
< Index
s then
    a Index e -> Index -> IO e
forall (a :: * -> * -> *) e (m :: * -> *).
MArray a e m =>
a Index e -> Index -> m e
readArray a Index e
a Index
i
  else
    [Char] -> IO e
forall a. HasCallStack => [Char] -> a
error ([Char] -> IO e) -> [Char] -> IO e
forall a b. (a -> b) -> a -> b
$ [Char]
"ToySolver.Internal.Data.Vec.read: index " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Index -> [Char]
forall a. Show a => a -> [Char]
show Index
i [Char] -> [Char] -> [Char]
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 :: GenericVec a e -> Index -> e -> IO ()
write !GenericVec a e
v !Index
i e
e = do
  a Index e
a <- GenericVec a e -> IO (a Index e)
forall (a :: * -> * -> *) e. GenericVec a e -> IO (a Index e)
getArray GenericVec a e
v
  Index
s <- GenericVec a e -> IO Index
forall (a :: * -> * -> *) e. GenericVec a e -> IO Index
getSize GenericVec a e
v
  if Index
0 Index -> Index -> Bool
forall a. Ord a => a -> a -> Bool
<= Index
i Bool -> Bool -> Bool
&& Index
i Index -> Index -> Bool
forall a. Ord a => a -> a -> Bool
< Index
s then
    a Index e -> Index -> e -> IO ()
forall (a :: * -> * -> *) e (m :: * -> *).
MArray a e m =>
a Index e -> Index -> e -> m ()
writeArray a Index e
a Index
i e
e
  else
    [Char] -> IO ()
forall a. HasCallStack => [Char] -> a
error ([Char] -> IO ()) -> [Char] -> IO ()
forall a b. (a -> b) -> a -> b
$ [Char]
"ToySolver.Internal.Data.Vec.write: index " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Index -> [Char]
forall a. Show a => a -> [Char]
show Index
i [Char] -> [Char] -> [Char]
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 :: GenericVec a e -> Index -> (e -> e) -> IO ()
modify !GenericVec a e
v !Index
i e -> e
f = do
  a Index e
a <- GenericVec a e -> IO (a Index e)
forall (a :: * -> * -> *) e. GenericVec a e -> IO (a Index e)
getArray GenericVec a e
v
  Index
s <- GenericVec a e -> IO Index
forall (a :: * -> * -> *) e. GenericVec a e -> IO Index
getSize GenericVec a e
v
  if Index
0 Index -> Index -> Bool
forall a. Ord a => a -> a -> Bool
<= Index
i Bool -> Bool -> Bool
&& Index
i Index -> Index -> Bool
forall a. Ord a => a -> a -> Bool
< Index
s then do
    e
x <- a Index e -> Index -> IO e
forall (a :: * -> * -> *) e (m :: * -> *).
MArray a e m =>
a Index e -> Index -> m e
readArray a Index e
a Index
i
    a Index e -> Index -> e -> IO ()
forall (a :: * -> * -> *) e (m :: * -> *).
MArray a e m =>
a Index e -> Index -> e -> m ()
writeArray a Index e
a Index
i (e -> e
f e
x)
  else
    [Char] -> IO ()
forall a. HasCallStack => [Char] -> a
error ([Char] -> IO ()) -> [Char] -> IO ()
forall a b. (a -> b) -> a -> b
$ [Char]
"ToySolver.Internal.Data.Vec.modify: index " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Index -> [Char]
forall a. Show a => a -> [Char]
show Index
i [Char] -> [Char] -> [Char]
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' :: GenericVec a e -> Index -> (e -> e) -> IO ()
modify' !GenericVec a e
v !Index
i e -> e
f = do
  a Index e
a <- GenericVec a e -> IO (a Index e)
forall (a :: * -> * -> *) e. GenericVec a e -> IO (a Index e)
getArray GenericVec a e
v
  Index
s <- GenericVec a e -> IO Index
forall (a :: * -> * -> *) e. GenericVec a e -> IO Index
getSize GenericVec a e
v
  if Index
0 Index -> Index -> Bool
forall a. Ord a => a -> a -> Bool
<= Index
i Bool -> Bool -> Bool
&& Index
i Index -> Index -> Bool
forall a. Ord a => a -> a -> Bool
< Index
s then do
    e
x <- a Index e -> Index -> IO e
forall (a :: * -> * -> *) e (m :: * -> *).
MArray a e m =>
a Index e -> Index -> m e
readArray a Index e
a Index
i
    a Index e -> Index -> e -> IO ()
forall (a :: * -> * -> *) e (m :: * -> *).
MArray a e m =>
a Index e -> Index -> e -> m ()
writeArray a Index e
a Index
i (e -> IO ()) -> e -> IO ()
forall a b. (a -> b) -> a -> b
$! e -> e
f e
x
  else
    [Char] -> IO ()
forall a. HasCallStack => [Char] -> a
error ([Char] -> IO ()) -> [Char] -> IO ()
forall a b. (a -> b) -> a -> b
$ [Char]
"ToySolver.Internal.Data.Vec.modify': index " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Index -> [Char]
forall a. Show a => a -> [Char]
show Index
i [Char] -> [Char] -> [Char]
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 :: GenericVec a e -> Index -> (e -> e) -> IO ()
unsafeModify !GenericVec a e
v !Index
i e -> e
f = do
  a Index e
a <- GenericVec a e -> IO (a Index e)
forall (a :: * -> * -> *) e. GenericVec a e -> IO (a Index e)
getArray GenericVec a e
v
  e
x <- a Index e -> Index -> IO e
forall (a :: * -> * -> *) e (m :: * -> *).
MArray a e m =>
a Index e -> Index -> m e
readArray a Index e
a Index
i
  a Index e -> Index -> e -> IO ()
forall (a :: * -> * -> *) e (m :: * -> *).
MArray a e m =>
a Index e -> Index -> e -> m ()
writeArray a Index e
a Index
i (e -> e
f e
x)

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

{-# INLINE unsafeWrite #-}
unsafeWrite :: A.MArray a e IO => GenericVec a e -> Int -> e -> IO ()
unsafeWrite :: GenericVec a e -> Index -> e -> IO ()
unsafeWrite !GenericVec a e
v !Index
i e
e = do
  a Index e
a <- GenericVec a e -> IO (a Index e)
forall (a :: * -> * -> *) e. GenericVec a e -> IO (a Index e)
getArray GenericVec a e
v
  a Index e -> Index -> e -> IO ()
forall (a :: * -> * -> *) e (m :: * -> *).
MArray a e m =>
a Index e -> Index -> e -> m ()
writeArray a Index e
a Index
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 :: GenericVec a e -> Index -> IO ()
resize v :: GenericVec a e
v@(GenericVec IOURef Index
sizeRef IORef (a Index e)
arrayRef) !Index
n = do
  a Index e
a <- GenericVec a e -> IO (a Index e)
forall (a :: * -> * -> *) e. GenericVec a e -> IO (a Index e)
getArray GenericVec a e
v
  Index
capa <- GenericVec a e -> IO Index
forall (a :: * -> * -> *) e.
MArray a e IO =>
GenericVec a e -> IO Index
getCapacity GenericVec a e
v
  Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (Index
n Index -> Index -> Bool
forall a. Ord a => a -> a -> Bool
<= Index
capa) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
    let capa' :: Index
capa' = Index -> Index -> Index
forall a. Ord a => a -> a -> a
max Index
2 (Index
capa Index -> Index -> Index
forall a. Num a => a -> a -> a
* Index
3 Index -> Index -> Index
forall a. Integral a => a -> a -> a
`div` Index
2)
    a Index e
a' <- (Index, Index) -> IO (a Index e)
forall (a :: * -> * -> *) e (m :: * -> *) i.
(MArray a e m, Ix i) =>
(i, i) -> m (a i e)
A.newArray_ (Index
0, Index
capa'Index -> Index -> Index
forall a. Num a => a -> a -> a
-Index
1)
    a Index e -> a Index e -> (Index, Index) -> IO ()
forall (a :: * -> * -> *) e (m :: * -> *).
MArray a e m =>
a Index e -> a Index e -> (Index, Index) -> m ()
copyTo a Index e
a a Index e
a' (Index
0,Index
capaIndex -> Index -> Index
forall a. Num a => a -> a -> a
-Index
1)
    IORef (a Index e) -> a Index e -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef IORef (a Index e)
arrayRef a Index e
a'
  IOURef Index -> Index -> IO ()
forall a. MArray IOUArray a IO => IOURef a -> a -> IO ()
writeIOURef IOURef Index
sizeRef Index
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 :: GenericVec a e -> Index -> IO ()
growTo GenericVec a e
v !Index
n = do
  Index
m <- GenericVec a e -> IO Index
forall (a :: * -> * -> *) e. GenericVec a e -> IO Index
getSize GenericVec a e
v
  Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Index
m Index -> Index -> Bool
forall a. Ord a => a -> a -> Bool
< Index
n) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ GenericVec a e -> Index -> IO ()
forall (a :: * -> * -> *) e.
MArray a e IO =>
GenericVec a e -> Index -> IO ()
resize GenericVec a e
v Index
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 :: GenericVec a e -> e -> IO ()
push GenericVec a e
v e
e = do
  Index
s <- GenericVec a e -> IO Index
forall (a :: * -> * -> *) e. GenericVec a e -> IO Index
getSize GenericVec a e
v
  GenericVec a e -> Index -> IO ()
forall (a :: * -> * -> *) e.
MArray a e IO =>
GenericVec a e -> Index -> IO ()
resize GenericVec a e
v (Index
sIndex -> Index -> Index
forall a. Num a => a -> a -> a
+Index
1)
  GenericVec a e -> Index -> e -> IO ()
forall (a :: * -> * -> *) e.
MArray a e IO =>
GenericVec a e -> Index -> e -> IO ()
unsafeWrite GenericVec a e
v Index
s e
e

popMaybe :: A.MArray a e IO => GenericVec a e -> IO (Maybe e)
popMaybe :: GenericVec a e -> IO (Maybe e)
popMaybe GenericVec a e
v = do
  Index
s <- GenericVec a e -> IO Index
forall (a :: * -> * -> *) e. GenericVec a e -> IO Index
getSize GenericVec a e
v
  if Index
s Index -> Index -> Bool
forall a. Eq a => a -> a -> Bool
== Index
0 then
    Maybe e -> IO (Maybe e)
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe e
forall a. Maybe a
Nothing
  else do
    e
e <- GenericVec a e -> Index -> IO e
forall (a :: * -> * -> *) e.
MArray a e IO =>
GenericVec a e -> Index -> IO e
unsafeRead GenericVec a e
v (Index
sIndex -> Index -> Index
forall a. Num a => a -> a -> a
-Index
1)
    GenericVec a e -> Index -> IO ()
forall (a :: * -> * -> *) e.
MArray a e IO =>
GenericVec a e -> Index -> IO ()
resize GenericVec a e
v (Index
sIndex -> Index -> Index
forall a. Num a => a -> a -> a
-Index
1)
    Maybe e -> IO (Maybe e)
forall (m :: * -> *) a. Monad m => a -> m a
return (e -> Maybe e
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 :: GenericVec a e -> IO e
pop GenericVec a e
v = do
  Index
s <- GenericVec a e -> IO Index
forall (a :: * -> * -> *) e. GenericVec a e -> IO Index
getSize GenericVec a e
v
  if Index
s Index -> Index -> Bool
forall a. Eq a => a -> a -> Bool
== Index
0 then
    [Char] -> IO e
forall a. HasCallStack => [Char] -> a
error ([Char] -> IO e) -> [Char] -> IO e
forall a b. (a -> b) -> a -> b
$ [Char]
"ToySolver.Internal.Data.Vec.pop: empty Vec"
  else do
    e
e <- GenericVec a e -> Index -> IO e
forall (a :: * -> * -> *) e.
MArray a e IO =>
GenericVec a e -> Index -> IO e
unsafeRead GenericVec a e
v (Index
sIndex -> Index -> Index
forall a. Num a => a -> a -> a
-Index
1)
    GenericVec a e -> Index -> IO ()
forall (a :: * -> * -> *) e.
MArray a e IO =>
GenericVec a e -> Index -> IO ()
resize GenericVec a e
v (Index
sIndex -> Index -> Index
forall a. Num a => a -> a -> a
-Index
1)
    e -> IO e
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 :: GenericVec a e -> IO e
unsafePop GenericVec a e
v = do
  Index
s <- GenericVec a e -> IO Index
forall (a :: * -> * -> *) e. GenericVec a e -> IO Index
getSize GenericVec a e
v
  e
e <- GenericVec a e -> Index -> IO e
forall (a :: * -> * -> *) e.
MArray a e IO =>
GenericVec a e -> Index -> IO e
unsafeRead GenericVec a e
v (Index
sIndex -> Index -> Index
forall a. Num a => a -> a -> a
-Index
1)
  GenericVec a e -> Index -> IO ()
forall (a :: * -> * -> *) e.
MArray a e IO =>
GenericVec a e -> Index -> IO ()
resize GenericVec a e
v (Index
sIndex -> Index -> Index
forall a. Num a => a -> a -> a
-Index
1)
  e -> IO e
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 :: GenericVec a e -> IO e
peek GenericVec a e
v = do
  Index
s <- GenericVec a e -> IO Index
forall (a :: * -> * -> *) e. GenericVec a e -> IO Index
getSize GenericVec a e
v
  if Index
s Index -> Index -> Bool
forall a. Eq a => a -> a -> Bool
== Index
0 then
    [Char] -> IO e
forall a. HasCallStack => [Char] -> a
error ([Char] -> IO e) -> [Char] -> IO e
forall a b. (a -> b) -> a -> b
$ [Char]
"ToySolver.Internal.Data.Vec.peek: empty Vec"
  else do
    GenericVec a e -> Index -> IO e
forall (a :: * -> * -> *) e.
MArray a e IO =>
GenericVec a e -> Index -> IO e
unsafeRead GenericVec a e
v (Index
sIndex -> Index -> Index
forall a. Num a => a -> a -> a
-Index
1)

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

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

getElems :: A.MArray a e IO => GenericVec a e -> IO [e]
getElems :: GenericVec a e -> IO [e]
getElems GenericVec a e
v = do
  Index
s <- GenericVec a e -> IO Index
forall (a :: * -> * -> *) e. GenericVec a e -> IO Index
getSize GenericVec a e
v
  [Index] -> (Index -> IO e) -> IO [e]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM [Index
0..Index
sIndex -> Index -> Index
forall a. Num a => a -> a -> a
-Index
1] ((Index -> IO e) -> IO [e]) -> (Index -> IO e) -> IO [e]
forall a b. (a -> b) -> a -> b
$ \Index
i -> GenericVec a e -> Index -> IO e
forall (a :: * -> * -> *) e.
MArray a e IO =>
GenericVec a e -> Index -> IO e
unsafeRead GenericVec a e
v Index
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 :: GenericVec a e -> IO (GenericVec a e)
clone (GenericVec IOURef Index
sizeRef IORef (a Index e)
arrayRef) = do
  a Index e
a <- IORef (a Index e) -> IO (a Index e)
forall a. IORef a -> IO a
readIORef IORef (a Index e)
arrayRef
  IORef (a Index e)
arrayRef' <- a Index e -> IO (IORef (a Index e))
forall a. a -> IO (IORef a)
newIORef (a Index e -> IO (IORef (a Index e)))
-> IO (a Index e) -> IO (IORef (a Index e))
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< a Index e -> IO (a Index e)
forall (a :: * -> * -> *) e (m :: * -> *).
MArray a e m =>
a Index e -> m (a Index e)
cloneArray a Index e
a
  IOURef Index
sizeRef'  <- Index -> IO (IOURef Index)
forall a. MArray IOUArray a IO => a -> IO (IOURef a)
newIOURef (Index -> IO (IOURef Index)) -> IO Index -> IO (IOURef Index)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< IOURef Index -> IO Index
forall a. MArray IOUArray a IO => IOURef a -> IO a
readIOURef IOURef Index
sizeRef
  GenericVec a e -> IO (GenericVec a e)
forall (m :: * -> *) a. Monad m => a -> m a
return (GenericVec a e -> IO (GenericVec a e))
-> GenericVec a e -> IO (GenericVec a e)
forall a b. (a -> b) -> a -> b
$ IOURef Index -> IORef (a Index e) -> GenericVec a e
forall (a :: * -> * -> *) e.
IOURef Index -> IORef (a Index e) -> GenericVec a e
GenericVec IOURef Index
sizeRef' IORef (a Index e)
arrayRef'

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

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

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

{-# INLINE getCapacity #-}
-- | Get the internal representation array
getCapacity :: A.MArray a e IO => GenericVec a e -> IO Int
getCapacity :: GenericVec a e -> IO Index
getCapacity GenericVec a e
vec = ((Index, Index) -> Index) -> IO (Index, Index) -> IO Index
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM (Index, Index) -> Index
forall a. Ix a => (a, a) -> Index
rangeSize (IO (Index, Index) -> IO Index) -> IO (Index, Index) -> IO Index
forall a b. (a -> b) -> a -> b
$ a Index e -> IO (Index, Index)
forall (a :: * -> * -> *) e (m :: * -> *) i.
(MArray a e m, Ix i) =>
a i e -> m (i, i)
A.getBounds (a Index e -> IO (Index, Index))
-> IO (a Index e) -> IO (Index, Index)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< GenericVec a e -> IO (a Index e)
forall (a :: * -> * -> *) e. GenericVec a e -> IO (a Index 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 :: GenericVec a e -> Index -> IO ()
resizeCapacity (GenericVec IOURef Index
sizeRef IORef (a Index e)
arrayRef) Index
capa = do
  Index
n <- IOURef Index -> IO Index
forall a. MArray IOUArray a IO => IOURef a -> IO a
readIOURef IOURef Index
sizeRef
  a Index e
arr <- IORef (a Index e) -> IO (a Index e)
forall a. IORef a -> IO a
readIORef IORef (a Index e)
arrayRef
  Index
capa0 <- ((Index, Index) -> Index) -> IO (Index, Index) -> IO Index
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM (Index, Index) -> Index
forall a. Ix a => (a, a) -> Index
rangeSize (IO (Index, Index) -> IO Index) -> IO (Index, Index) -> IO Index
forall a b. (a -> b) -> a -> b
$ a Index e -> IO (Index, Index)
forall (a :: * -> * -> *) e (m :: * -> *) i.
(MArray a e m, Ix i) =>
a i e -> m (i, i)
A.getBounds a Index e
arr
  Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Index
capa0 Index -> Index -> Bool
forall a. Ord a => a -> a -> Bool
< Index
capa) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
    let capa' :: Index
capa' = Index -> Index -> Index
forall a. Ord a => a -> a -> a
max Index
capa (Index
n Index -> Index -> Index
forall a. Num a => a -> a -> a
* Index
3 Index -> Index -> Index
forall a. Integral a => a -> a -> a
`div` Index
2)
    a Index e
arr' <- (Index, Index) -> IO (a Index e)
forall (a :: * -> * -> *) e (m :: * -> *) i.
(MArray a e m, Ix i) =>
(i, i) -> m (a i e)
A.newArray_ (Index
0, Index
capa'Index -> Index -> Index
forall a. Num a => a -> a -> a
-Index
1)
    a Index e -> a Index e -> (Index, Index) -> IO ()
forall (a :: * -> * -> *) e (m :: * -> *).
MArray a e m =>
a Index e -> a Index e -> (Index, Index) -> m ()
copyTo a Index e
arr a Index e
arr' (Index
0, Index
nIndex -> Index -> Index
forall a. Num a => a -> a -> a
-Index
1)
    IORef (a Index e) -> a Index e -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef IORef (a Index e)
arrayRef a Index e
arr'

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

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

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