{-# 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
$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
/= :: 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 = a Int e -> Int -> m e
forall i. Ix i => a i e -> Int -> m e
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 = a Int e -> Int -> e -> m ()
forall i. Ix i => a i e -> Int -> e -> m ()
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 <- Int -> IO (IOURef Int)
forall a. MArray IOUArray a IO => a -> IO (IOURef a)
newIOURef Int
0
  IORef (a Int e)
arrayRef <- a Int e -> IO (IORef (a Int e))
forall a. a -> IO (IORef a)
newIORef (a Int e -> IO (IORef (a Int e)))
-> IO (a Int e) -> IO (IORef (a Int e))
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< (Int, Int) -> IO (a Int e)
forall i. Ix i => (i, i) -> IO (a i e)
forall (a :: * -> * -> *) e (m :: * -> *) i.
(MArray a e m, Ix i) =>
(i, i) -> m (a i e)
A.newArray_ (Int
0,-Int
1)
  GenericVec a e -> IO (GenericVec a e)
forall a. a -> IO a
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 Int -> IORef (a Int e) -> GenericVec a e
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)
_) = IOURef Int -> IO Int
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 <- GenericVec a e -> IO (a Int e)
forall (a :: * -> * -> *) e. GenericVec a e -> IO (a Int e)
getArray GenericVec a e
v
  Int
s <- GenericVec a e -> IO Int
forall (a :: * -> * -> *) e. GenericVec a e -> IO Int
getSize GenericVec a e
v
  if Int
0 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
i Bool -> Bool -> Bool
&& Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
s then
    a Int e -> Int -> IO e
forall (a :: * -> * -> *) e (m :: * -> *).
MArray a e m =>
a Int e -> Int -> m e
readArray a Int e
a Int
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]
++ Int -> [Char]
forall a. Show a => a -> [Char]
show Int
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 :: 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 <- GenericVec a e -> IO (a Int e)
forall (a :: * -> * -> *) e. GenericVec a e -> IO (a Int e)
getArray GenericVec a e
v
  Int
s <- GenericVec a e -> IO Int
forall (a :: * -> * -> *) e. GenericVec a e -> IO Int
getSize GenericVec a e
v
  if Int
0 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
i Bool -> Bool -> Bool
&& Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
s then
    a Int e -> Int -> e -> IO ()
forall (a :: * -> * -> *) e (m :: * -> *).
MArray a e m =>
a Int e -> Int -> e -> m ()
writeArray a Int e
a Int
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]
++ Int -> [Char]
forall a. Show a => a -> [Char]
show Int
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 :: 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 <- GenericVec a e -> IO (a Int e)
forall (a :: * -> * -> *) e. GenericVec a e -> IO (a Int e)
getArray GenericVec a e
v
  Int
s <- GenericVec a e -> IO Int
forall (a :: * -> * -> *) e. GenericVec a e -> IO Int
getSize GenericVec a e
v
  if Int
0 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
i Bool -> Bool -> Bool
&& Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
s then do
    e
x <- a Int e -> Int -> IO e
forall (a :: * -> * -> *) e (m :: * -> *).
MArray a e m =>
a Int e -> Int -> m e
readArray a Int e
a Int
i
    a Int e -> Int -> e -> IO ()
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
    [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]
++ Int -> [Char]
forall a. Show a => a -> [Char]
show Int
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' :: 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 <- GenericVec a e -> IO (a Int e)
forall (a :: * -> * -> *) e. GenericVec a e -> IO (a Int e)
getArray GenericVec a e
v
  Int
s <- GenericVec a e -> IO Int
forall (a :: * -> * -> *) e. GenericVec a e -> IO Int
getSize GenericVec a e
v
  if Int
0 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
i Bool -> Bool -> Bool
&& Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
s then do
    e
x <- a Int e -> Int -> IO e
forall (a :: * -> * -> *) e (m :: * -> *).
MArray a e m =>
a Int e -> Int -> m e
readArray a Int e
a Int
i
    a Int e -> Int -> e -> IO ()
forall (a :: * -> * -> *) e (m :: * -> *).
MArray a e m =>
a Int e -> Int -> e -> m ()
writeArray a Int e
a Int
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]
++ Int -> [Char]
forall a. Show a => a -> [Char]
show Int
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 :: 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 <- GenericVec a e -> IO (a Int e)
forall (a :: * -> * -> *) e. GenericVec a e -> IO (a Int e)
getArray GenericVec a e
v
  e
x <- a Int e -> Int -> IO e
forall (a :: * -> * -> *) e (m :: * -> *).
MArray a e m =>
a Int e -> Int -> m e
readArray a Int e
a Int
i
  a Int e -> Int -> e -> IO ()
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 <- GenericVec a e -> IO (a Int e)
forall (a :: * -> * -> *) e. GenericVec a e -> IO (a Int e)
getArray GenericVec a e
v
  e
x <- a Int e -> Int -> IO e
forall (a :: * -> * -> *) e (m :: * -> *).
MArray a e m =>
a Int e -> Int -> m e
readArray a Int e
a Int
i
  a Int e -> Int -> e -> IO ()
forall (a :: * -> * -> *) e (m :: * -> *).
MArray a e m =>
a Int e -> Int -> e -> m ()
writeArray a Int e
a Int
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 :: 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 <- GenericVec a e -> IO (a Int e)
forall (a :: * -> * -> *) e. GenericVec a e -> IO (a Int e)
getArray GenericVec a e
v
  a Int e -> Int -> IO e
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 <- GenericVec a e -> IO (a Int e)
forall (a :: * -> * -> *) e. GenericVec a e -> IO (a Int e)
getArray GenericVec a e
v
  a Int e -> Int -> e -> IO ()
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 <- GenericVec a e -> IO (a Int e)
forall (a :: * -> * -> *) e. GenericVec a e -> IO (a Int e)
getArray GenericVec a e
v
  Int
capa <- GenericVec a e -> IO Int
forall (a :: * -> * -> *) e.
MArray a e IO =>
GenericVec a e -> IO Int
getCapacity GenericVec a e
v
  Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
capa) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
    let capa' :: Int
capa' = Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
2 (Int
capa Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
3 Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
2)
    a Int e
a' <- (Int, Int) -> IO (a Int e)
forall i. Ix i => (i, i) -> IO (a i e)
forall (a :: * -> * -> *) e (m :: * -> *) i.
(MArray a e m, Ix i) =>
(i, i) -> m (a i e)
A.newArray_ (Int
0, Int
capa'Int -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1)
    a Int e -> a Int e -> (Int, Int) -> IO ()
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
capaInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1)
    IORef (a Int e) -> a Int e -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef IORef (a Int e)
arrayRef a Int e
a'
  IOURef Int -> Int -> IO ()
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 <- GenericVec a e -> IO Int
forall (a :: * -> * -> *) e. GenericVec a e -> IO Int
getSize GenericVec a e
v
  Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Int
m Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
n) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ GenericVec a e -> Int -> IO ()
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 <- GenericVec a e -> IO Int
forall (a :: * -> * -> *) e. GenericVec a e -> IO Int
getSize GenericVec a e
v
  GenericVec a e -> Int -> IO ()
forall (a :: * -> * -> *) e.
MArray a e IO =>
GenericVec a e -> Int -> IO ()
resize GenericVec a e
v (Int
sInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1)
  GenericVec a e -> Int -> e -> IO ()
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 <- GenericVec a e -> IO Int
forall (a :: * -> * -> *) e. GenericVec a e -> IO Int
getSize GenericVec a e
v
  if Int
s Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 then
    Maybe e -> IO (Maybe e)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe e
forall a. Maybe a
Nothing
  else do
    e
e <- GenericVec a e -> Int -> IO e
forall (a :: * -> * -> *) e.
MArray a e IO =>
GenericVec a e -> Int -> IO e
unsafeRead GenericVec a e
v (Int
sInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1)
    GenericVec a e -> Int -> IO ()
forall (a :: * -> * -> *) e.
MArray a e IO =>
GenericVec a e -> Int -> IO ()
resize GenericVec a e
v (Int
sInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1)
    Maybe e -> IO (Maybe e)
forall a. a -> IO a
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 :: forall (a :: * -> * -> *) e.
MArray a e IO =>
GenericVec a e -> IO e
pop GenericVec a e
v = do
  Int
s <- GenericVec a e -> IO Int
forall (a :: * -> * -> *) e. GenericVec a e -> IO Int
getSize GenericVec a e
v
  if Int
s Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
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 -> Int -> IO e
forall (a :: * -> * -> *) e.
MArray a e IO =>
GenericVec a e -> Int -> IO e
unsafeRead GenericVec a e
v (Int
sInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1)
    GenericVec a e -> Int -> IO ()
forall (a :: * -> * -> *) e.
MArray a e IO =>
GenericVec a e -> Int -> IO ()
resize GenericVec a e
v (Int
sInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1)
    e -> IO e
forall a. a -> IO a
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 <- GenericVec a e -> IO Int
forall (a :: * -> * -> *) e. GenericVec a e -> IO Int
getSize GenericVec a e
v
  e
e <- GenericVec a e -> Int -> IO e
forall (a :: * -> * -> *) e.
MArray a e IO =>
GenericVec a e -> Int -> IO e
unsafeRead GenericVec a e
v (Int
sInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1)
  GenericVec a e -> Int -> IO ()
forall (a :: * -> * -> *) e.
MArray a e IO =>
GenericVec a e -> Int -> IO ()
resize GenericVec a e
v (Int
sInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1)
  e -> IO e
forall a. a -> IO a
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 <- GenericVec a e -> IO Int
forall (a :: * -> * -> *) e. GenericVec a e -> IO Int
getSize GenericVec a e
v
  if Int
s Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
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 -> Int -> IO e
forall (a :: * -> * -> *) e.
MArray a e IO =>
GenericVec a e -> Int -> IO e
unsafeRead GenericVec a e
v (Int
sInt -> Int -> Int
forall 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 <- GenericVec a e -> IO Int
forall (a :: * -> * -> *) e. GenericVec a e -> IO Int
getSize GenericVec a e
v
  GenericVec a e -> Int -> IO e
forall (a :: * -> * -> *) e.
MArray a e IO =>
GenericVec a e -> Int -> IO e
unsafeRead GenericVec a e
v (Int
sInt -> Int -> Int
forall 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 = GenericVec a e -> Int -> IO ()
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 <- GenericVec a e -> IO Int
forall (a :: * -> * -> *) e. GenericVec a e -> IO Int
getSize GenericVec a e
v
  [Int] -> (Int -> IO e) -> IO [e]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM [Int
0..Int
sInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1] ((Int -> IO e) -> IO [e]) -> (Int -> IO e) -> IO [e]
forall a b. (a -> b) -> a -> b
$ \Int
i -> GenericVec a e -> Int -> IO e
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 <- IORef (a Int e) -> IO (a Int e)
forall a. IORef a -> IO a
readIORef IORef (a Int e)
arrayRef
  IORef (a Int e)
arrayRef' <- a Int e -> IO (IORef (a Int e))
forall a. a -> IO (IORef a)
newIORef (a Int e -> IO (IORef (a Int e)))
-> IO (a Int e) -> IO (IORef (a Int e))
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< a Int e -> IO (a Int e)
forall (a :: * -> * -> *) e (m :: * -> *).
MArray a e m =>
a Int e -> m (a Int e)
cloneArray a Int e
a
  IOURef Int
sizeRef'  <- Int -> IO (IOURef Int)
forall a. MArray IOUArray a IO => a -> IO (IOURef a)
newIOURef (Int -> IO (IOURef Int)) -> IO Int -> IO (IOURef Int)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< IOURef Int -> IO Int
forall a. MArray IOUArray a IO => IOURef a -> IO a
readIOURef IOURef Int
sizeRef
  GenericVec a e -> IO (GenericVec a e)
forall a. a -> IO a
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 Int -> IORef (a Int e) -> GenericVec a e
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) = IORef (a Int e) -> IO (a Int e)
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 = ((Int, Int) -> Int) -> IO (Int, Int) -> IO Int
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM (Int, Int) -> Int
forall a. Ix a => (a, a) -> Int
rangeSize (IO (Int, Int) -> IO Int) -> IO (Int, Int) -> IO Int
forall a b. (a -> b) -> a -> b
$ a Int e -> IO (Int, Int)
forall i. Ix i => a i e -> IO (i, i)
forall (a :: * -> * -> *) e (m :: * -> *) i.
(MArray a e m, Ix i) =>
a i e -> m (i, i)
A.getBounds (a Int e -> IO (Int, Int)) -> IO (a Int e) -> IO (Int, Int)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< GenericVec a e -> IO (a Int e)
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 <- IOURef Int -> IO Int
forall a. MArray IOUArray a IO => IOURef a -> IO a
readIOURef IOURef Int
sizeRef
  a Int e
arr <- IORef (a Int e) -> IO (a Int e)
forall a. IORef a -> IO a
readIORef IORef (a Int e)
arrayRef
  Int
capa0 <- ((Int, Int) -> Int) -> IO (Int, Int) -> IO Int
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM (Int, Int) -> Int
forall a. Ix a => (a, a) -> Int
rangeSize (IO (Int, Int) -> IO Int) -> IO (Int, Int) -> IO Int
forall a b. (a -> b) -> a -> b
$ a Int e -> IO (Int, Int)
forall i. Ix i => a i e -> IO (i, i)
forall (a :: * -> * -> *) e (m :: * -> *) i.
(MArray a e m, Ix i) =>
a i e -> m (i, i)
A.getBounds a Int e
arr
  Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Int
capa0 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
capa) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
    let capa' :: Int
capa' = Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
capa (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
3 Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
2)
    a Int e
arr' <- (Int, Int) -> IO (a Int e)
forall i. Ix i => (i, i) -> IO (a i e)
forall (a :: * -> * -> *) e (m :: * -> *) i.
(MArray a e m, Ix i) =>
(i, i) -> m (a i e)
A.newArray_ (Int
0, Int
capa'Int -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1)
    a Int e -> a Int e -> (Int, Int) -> IO ()
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
nInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1)
    IORef (a Int e) -> a Int e -> IO ()
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 <- a Int e -> m (Int, Int)
forall i. Ix i => a i e -> m (i, i)
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' <- (Int, Int) -> m (a Int e)
forall i. Ix i => (i, i) -> m (a i e)
forall (a :: * -> * -> *) e (m :: * -> *) i.
(MArray a e m, Ix i) =>
(i, i) -> m (a i e)
A.newArray_ (Int, Int)
b
  a Int e -> a Int e -> (Int, Int) -> m ()
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
  a Int e -> m (a Int e)
forall a. a -> m a
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
  Int -> (Int -> Bool) -> (Int -> Int) -> (Int -> m ()) -> m ()
forall (m :: * -> *) a.
Monad m =>
a -> (a -> Bool) -> (a -> a) -> (a -> m ()) -> m ()
forLoop Int
lb (Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<=Int
ub) (Int -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1) ((Int -> m ()) -> m ()) -> (Int -> m ()) -> m ()
forall a b. (a -> b) -> a -> b
$ \Int
i -> do
    e
val_i <- a Int e -> Int -> m e
forall (a :: * -> * -> *) e (m :: * -> *).
MArray a e m =>
a Int e -> Int -> m e
readArray a Int e
fromArr Int
i
    a Int e -> Int -> e -> m ()
forall (a :: * -> * -> *) e (m :: * -> *).
MArray a e m =>
a Int e -> Int -> e -> m ()
writeArray a Int e
toArr Int
i e
val_i