{-# LANGUAGE FlexibleContexts #-}

-- |
-- Module     : Simulation.Aivika.Vector
-- Copyright  : Copyright (c) 2009-2017, David Sorokin <david.sorokin@gmail.com>
-- License    : BSD3
-- Maintainer : David Sorokin <david.sorokin@gmail.com>
-- Stability  : experimental
-- Tested with: GHC 8.0.1
--
-- An imperative vector.
--
module Simulation.Aivika.Vector
       (Vector, 
        newVector, 
        copyVector,
        vectorCount, 
        appendVector, 
        readVector, 
        writeVector,
        vectorBinarySearch,
        vectorInsert,
        vectorDeleteAt,
        vectorDeleteRange,
        vectorDelete,
        vectorDeleteBy,
        vectorIndex,
        vectorIndexBy,
        vectorContains,
        vectorContainsBy,
        freezeVector) where 

import Data.Array
import Data.Array.MArray.Safe
import Data.Array.IO.Safe
import Data.IORef
import Control.Monad

-- | Represents a resizable vector.
data Vector a = Vector { Vector a -> IORef (IOArray Int a)
vectorArrayRef :: IORef (IOArray Int a),
                         Vector a -> IORef Int
vectorCountRef :: IORef Int, 
                         Vector a -> IORef Int
vectorCapacityRef :: IORef Int }

-- | Create a new vector.
newVector :: IO (Vector a)
newVector :: IO (Vector a)
newVector = 
  do IOArray Int a
array <- (Int, Int) -> IO (IOArray Int a)
forall (a :: * -> * -> *) e (m :: * -> *) i.
(MArray a e m, Ix i) =>
(i, i) -> m (a i e)
newArray_ (Int
0, Int
4 Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)
     IORef (IOArray Int a)
arrayRef <- IOArray Int a -> IO (IORef (IOArray Int a))
forall a. a -> IO (IORef a)
newIORef IOArray Int a
array
     IORef Int
countRef <- Int -> IO (IORef Int)
forall a. a -> IO (IORef a)
newIORef Int
0
     IORef Int
capacityRef <- Int -> IO (IORef Int)
forall a. a -> IO (IORef a)
newIORef Int
4
     Vector a -> IO (Vector a)
forall (m :: * -> *) a. Monad m => a -> m a
return Vector :: forall a.
IORef (IOArray Int a) -> IORef Int -> IORef Int -> Vector a
Vector { vectorArrayRef :: IORef (IOArray Int a)
vectorArrayRef = IORef (IOArray Int a)
arrayRef,
                     vectorCountRef :: IORef Int
vectorCountRef = IORef Int
countRef,
                     vectorCapacityRef :: IORef Int
vectorCapacityRef = IORef Int
capacityRef }

-- | Copy the vector.
copyVector :: Vector a -> IO (Vector a)
copyVector :: Vector a -> IO (Vector a)
copyVector Vector a
vector =
  do IOArray Int a
array <- IORef (IOArray Int a) -> IO (IOArray Int a)
forall a. IORef a -> IO a
readIORef (Vector a -> IORef (IOArray Int a)
forall a. Vector a -> IORef (IOArray Int a)
vectorArrayRef Vector a
vector)
     Int
count <- IORef Int -> IO Int
forall a. IORef a -> IO a
readIORef (Vector a -> IORef Int
forall a. Vector a -> IORef Int
vectorCountRef Vector a
vector)
     IOArray Int a
array' <- (Int, Int) -> IO (IOArray Int a)
forall (a :: * -> * -> *) e (m :: * -> *) i.
(MArray a e m, Ix i) =>
(i, i) -> m (a i e)
newArray_ (Int
0, Int
count Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)
     IORef (IOArray Int a)
arrayRef' <- IOArray Int a -> IO (IORef (IOArray Int a))
forall a. a -> IO (IORef a)
newIORef IOArray Int a
array'
     IORef Int
countRef' <- Int -> IO (IORef Int)
forall a. a -> IO (IORef a)
newIORef Int
count
     IORef Int
capacityRef' <- Int -> IO (IORef Int)
forall a. a -> IO (IORef a)
newIORef Int
count
     [Int] -> (Int -> IO ()) -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ [Int
0 .. Int
count Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1] ((Int -> IO ()) -> IO ()) -> (Int -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Int
i ->
       do a
x <- IOArray Int a -> Int -> IO a
forall (a :: * -> * -> *) e (m :: * -> *) i.
(MArray a e m, Ix i) =>
a i e -> i -> m e
readArray IOArray Int a
array Int
i
          IOArray Int a -> Int -> a -> IO ()
forall (a :: * -> * -> *) e (m :: * -> *) i.
(MArray a e m, Ix i) =>
a i e -> i -> e -> m ()
writeArray IOArray Int a
array' Int
i a
x
     Vector a -> IO (Vector a)
forall (m :: * -> *) a. Monad m => a -> m a
return Vector :: forall a.
IORef (IOArray Int a) -> IORef Int -> IORef Int -> Vector a
Vector { vectorArrayRef :: IORef (IOArray Int a)
vectorArrayRef = IORef (IOArray Int a)
arrayRef',
                     vectorCountRef :: IORef Int
vectorCountRef = IORef Int
countRef',
                     vectorCapacityRef :: IORef Int
vectorCapacityRef = IORef Int
capacityRef' }

-- | Ensure that the vector has the specified capacity.
vectorEnsureCapacity :: Vector a -> Int -> IO ()
vectorEnsureCapacity :: Vector a -> Int -> IO ()
vectorEnsureCapacity Vector a
vector Int
capacity =
  do Int
capacity' <- IORef Int -> IO Int
forall a. IORef a -> IO a
readIORef (Vector a -> IORef Int
forall a. Vector a -> IORef Int
vectorCapacityRef Vector a
vector)
     Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Int
capacity' Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
capacity) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$
       do IOArray Int a
array' <- IORef (IOArray Int a) -> IO (IOArray Int a)
forall a. IORef a -> IO a
readIORef (Vector a -> IORef (IOArray Int a)
forall a. Vector a -> IORef (IOArray Int a)
vectorArrayRef Vector a
vector)
          Int
count' <- IORef Int -> IO Int
forall a. IORef a -> IO a
readIORef (Vector a -> IORef Int
forall a. Vector a -> IORef Int
vectorCountRef Vector a
vector)
          let capacity'' :: Int
capacity'' = Int -> Int -> Int
forall a. Ord a => a -> a -> a
max (Int
2 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
capacity') Int
capacity
          IOArray Int a
array'' <- (Int, Int) -> IO (IOArray Int a)
forall (a :: * -> * -> *) e (m :: * -> *) i.
(MArray a e m, Ix i) =>
(i, i) -> m (a i e)
newArray_ (Int
0, Int
capacity'' Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)
          [Int] -> (Int -> IO ()) -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ [Int
0 .. Int
count' Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1] ((Int -> IO ()) -> IO ()) -> (Int -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Int
i ->
            do a
x <- IOArray Int a -> Int -> IO a
forall (a :: * -> * -> *) e (m :: * -> *) i.
(MArray a e m, Ix i) =>
a i e -> i -> m e
readArray IOArray Int a
array' Int
i
               IOArray Int a -> Int -> a -> IO ()
forall (a :: * -> * -> *) e (m :: * -> *) i.
(MArray a e m, Ix i) =>
a i e -> i -> e -> m ()
writeArray IOArray Int a
array'' Int
i a
x
          IORef (IOArray Int a) -> IOArray Int a -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef (Vector a -> IORef (IOArray Int a)
forall a. Vector a -> IORef (IOArray Int a)
vectorArrayRef Vector a
vector) IOArray Int a
array''
          IORef Int -> Int -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef (Vector a -> IORef Int
forall a. Vector a -> IORef Int
vectorCapacityRef Vector a
vector) Int
capacity''
          
-- | Return the element count.
vectorCount :: Vector a -> IO Int
vectorCount :: Vector a -> IO Int
vectorCount Vector a
vector = IORef Int -> IO Int
forall a. IORef a -> IO a
readIORef (Vector a -> IORef Int
forall a. Vector a -> IORef Int
vectorCountRef Vector a
vector)
          
-- | Add the specified element to the end of the vector.
appendVector :: Vector a -> a -> IO ()          
appendVector :: Vector a -> a -> IO ()
appendVector Vector a
vector a
item =
  do Int
count <- IORef Int -> IO Int
forall a. IORef a -> IO a
readIORef (Vector a -> IORef Int
forall a. Vector a -> IORef Int
vectorCountRef Vector a
vector)
     Vector a -> Int -> IO ()
forall a. Vector a -> Int -> IO ()
vectorEnsureCapacity Vector a
vector (Int
count Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
     IOArray Int a
array <- IORef (IOArray Int a) -> IO (IOArray Int a)
forall a. IORef a -> IO a
readIORef (Vector a -> IORef (IOArray Int a)
forall a. Vector a -> IORef (IOArray Int a)
vectorArrayRef Vector a
vector)
     IOArray Int a -> Int -> a -> IO ()
forall (a :: * -> * -> *) e (m :: * -> *) i.
(MArray a e m, Ix i) =>
a i e -> i -> e -> m ()
writeArray IOArray Int a
array Int
count a
item
     IORef Int -> Int -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef (Vector a -> IORef Int
forall a. Vector a -> IORef Int
vectorCountRef Vector a
vector) (Int
count Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
     
-- | Read a value from the vector, where indices are started from 0.
readVector :: Vector a -> Int -> IO a
readVector :: Vector a -> Int -> IO a
readVector Vector a
vector Int
index =
  do IOArray Int a
array <- IORef (IOArray Int a) -> IO (IOArray Int a)
forall a. IORef a -> IO a
readIORef (Vector a -> IORef (IOArray Int a)
forall a. Vector a -> IORef (IOArray Int a)
vectorArrayRef Vector a
vector)
     IOArray Int a -> Int -> IO a
forall (a :: * -> * -> *) e (m :: * -> *) i.
(MArray a e m, Ix i) =>
a i e -> i -> m e
readArray IOArray Int a
array Int
index
          
-- | Set an array item at the specified index which is started from 0.
writeVector :: Vector a -> Int -> a -> IO ()
writeVector :: Vector a -> Int -> a -> IO ()
writeVector Vector a
vector Int
index a
item =
  do IOArray Int a
array <- IORef (IOArray Int a) -> IO (IOArray Int a)
forall a. IORef a -> IO a
readIORef (Vector a -> IORef (IOArray Int a)
forall a. Vector a -> IORef (IOArray Int a)
vectorArrayRef Vector a
vector)
     IOArray Int a -> Int -> a -> IO ()
forall (a :: * -> * -> *) e (m :: * -> *) i.
(MArray a e m, Ix i) =>
a i e -> i -> e -> m ()
writeArray IOArray Int a
array Int
index a
item

vectorBinarySearch' :: Ord a => IOArray Int a -> a -> Int -> Int -> IO Int
vectorBinarySearch' :: IOArray Int a -> a -> Int -> Int -> IO Int
vectorBinarySearch' IOArray Int a
array a
item Int
left Int
right =
  if Int
left Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
right 
  then Int -> IO Int
forall (m :: * -> *) a. Monad m => a -> m a
return (Int -> IO Int) -> Int -> IO Int
forall a b. (a -> b) -> a -> b
$ - (Int
right Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1
  else
    do let index :: Int
index = (Int
left Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
right) Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
2
       a
curr <- IOArray Int a -> Int -> IO a
forall (a :: * -> * -> *) e (m :: * -> *) i.
(MArray a e m, Ix i) =>
a i e -> i -> m e
readArray IOArray Int a
array Int
index
       if a
item a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< a
curr 
         then IOArray Int a -> a -> Int -> Int -> IO Int
forall a. Ord a => IOArray Int a -> a -> Int -> Int -> IO Int
vectorBinarySearch' IOArray Int a
array a
item Int
left (Int
index Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)
         else if a
item a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
curr
              then Int -> IO Int
forall (m :: * -> *) a. Monad m => a -> m a
return Int
index
              else IOArray Int a -> a -> Int -> Int -> IO Int
forall a. Ord a => IOArray Int a -> a -> Int -> Int -> IO Int
vectorBinarySearch' IOArray Int a
array a
item (Int
index Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) Int
right
                   
-- | Return the index of the specified element using binary search; otherwise, 
-- a negated insertion index minus one: 0 -> -0 - 1, ..., i -> -i - 1, ....
vectorBinarySearch :: Ord a => Vector a -> a -> IO Int
vectorBinarySearch :: Vector a -> a -> IO Int
vectorBinarySearch Vector a
vector a
item =
  do IOArray Int a
array <- IORef (IOArray Int a) -> IO (IOArray Int a)
forall a. IORef a -> IO a
readIORef (Vector a -> IORef (IOArray Int a)
forall a. Vector a -> IORef (IOArray Int a)
vectorArrayRef Vector a
vector)
     Int
count <- IORef Int -> IO Int
forall a. IORef a -> IO a
readIORef (Vector a -> IORef Int
forall a. Vector a -> IORef Int
vectorCountRef Vector a
vector)
     IOArray Int a -> a -> Int -> Int -> IO Int
forall a. Ord a => IOArray Int a -> a -> Int -> Int -> IO Int
vectorBinarySearch' IOArray Int a
array a
item Int
0 (Int
count Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)

-- | Return the elements of the vector in an immutable array.
freezeVector :: Vector a -> IO (Array Int a)
freezeVector :: Vector a -> IO (Array Int a)
freezeVector Vector a
vector = 
  do Vector a
vector' <- Vector a -> IO (Vector a)
forall a. Vector a -> IO (Vector a)
copyVector Vector a
vector
     IOArray Int a
array   <- IORef (IOArray Int a) -> IO (IOArray Int a)
forall a. IORef a -> IO a
readIORef (Vector a -> IORef (IOArray Int a)
forall a. Vector a -> IORef (IOArray Int a)
vectorArrayRef Vector a
vector')
     IOArray Int a -> IO (Array Int a)
forall i (a :: * -> * -> *) e (m :: * -> *) (b :: * -> * -> *).
(Ix i, MArray a e m, IArray b e) =>
a i e -> m (b i e)
freeze IOArray Int a
array
     
-- | Insert the element in the vector at the specified index.
vectorInsert :: Vector a -> Int -> a -> IO ()          
vectorInsert :: Vector a -> Int -> a -> IO ()
vectorInsert Vector a
vector Int
index a
item =
  do Int
count <- IORef Int -> IO Int
forall a. IORef a -> IO a
readIORef (Vector a -> IORef Int
forall a. Vector a -> IORef Int
vectorCountRef Vector a
vector)
     Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Int
index Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$
       [Char] -> IO ()
forall a. HasCallStack => [Char] -> a
error ([Char] -> IO ()) -> [Char] -> IO ()
forall a b. (a -> b) -> a -> b
$
       [Char]
"Index cannot be " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++
       [Char]
"negative: vectorInsert."
     Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Int
index Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
count) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$
       [Char] -> IO ()
forall a. HasCallStack => [Char] -> a
error ([Char] -> IO ()) -> [Char] -> IO ()
forall a b. (a -> b) -> a -> b
$
       [Char]
"Index cannot be greater " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++
       [Char]
"than the count: vectorInsert."
     Vector a -> Int -> IO ()
forall a. Vector a -> Int -> IO ()
vectorEnsureCapacity Vector a
vector (Int
count Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
     IOArray Int a
array <- IORef (IOArray Int a) -> IO (IOArray Int a)
forall a. IORef a -> IO a
readIORef (Vector a -> IORef (IOArray Int a)
forall a. Vector a -> IORef (IOArray Int a)
vectorArrayRef Vector a
vector)
     [Int] -> (Int -> IO ()) -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ [Int
count, Int
count Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1 .. Int
index Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1] ((Int -> IO ()) -> IO ()) -> (Int -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Int
i ->
       do a
x <- IOArray Int a -> Int -> IO a
forall (a :: * -> * -> *) e (m :: * -> *) i.
(MArray a e m, Ix i) =>
a i e -> i -> m e
readArray IOArray Int a
array (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)
          IOArray Int a -> Int -> a -> IO ()
forall (a :: * -> * -> *) e (m :: * -> *) i.
(MArray a e m, Ix i) =>
a i e -> i -> e -> m ()
writeArray IOArray Int a
array Int
i a
x
     IOArray Int a -> Int -> a -> IO ()
forall (a :: * -> * -> *) e (m :: * -> *) i.
(MArray a e m, Ix i) =>
a i e -> i -> e -> m ()
writeArray IOArray Int a
array Int
index a
item
     IORef Int -> Int -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef (Vector a -> IORef Int
forall a. Vector a -> IORef Int
vectorCountRef Vector a
vector) (Int
count Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
     
-- | Delete the element at the specified index.
vectorDeleteAt :: Vector a -> Int -> IO ()
vectorDeleteAt :: Vector a -> Int -> IO ()
vectorDeleteAt Vector a
vector Int
index =
  do Int
count <- IORef Int -> IO Int
forall a. IORef a -> IO a
readIORef (Vector a -> IORef Int
forall a. Vector a -> IORef Int
vectorCountRef Vector a
vector)
     Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Int
index Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$
       [Char] -> IO ()
forall a. HasCallStack => [Char] -> a
error ([Char] -> IO ()) -> [Char] -> IO ()
forall a b. (a -> b) -> a -> b
$
       [Char]
"Index cannot be " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++
       [Char]
"negative: vectorDeleteAt."
     Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Int
index Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
count) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$
       [Char] -> IO ()
forall a. HasCallStack => [Char] -> a
error ([Char] -> IO ()) -> [Char] -> IO ()
forall a b. (a -> b) -> a -> b
$
       [Char]
"Index must be less " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++
       [Char]
"than the count: vectorDeleteAt."
     IOArray Int a
array <- IORef (IOArray Int a) -> IO (IOArray Int a)
forall a. IORef a -> IO a
readIORef (Vector a -> IORef (IOArray Int a)
forall a. Vector a -> IORef (IOArray Int a)
vectorArrayRef Vector a
vector)
     [Int] -> (Int -> IO ()) -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ [Int
index, Int
index Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1 .. Int
count Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
2] ((Int -> IO ()) -> IO ()) -> (Int -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Int
i ->
       do a
x <- IOArray Int a -> Int -> IO a
forall (a :: * -> * -> *) e (m :: * -> *) i.
(MArray a e m, Ix i) =>
a i e -> i -> m e
readArray IOArray Int a
array (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
          IOArray Int a -> Int -> a -> IO ()
forall (a :: * -> * -> *) e (m :: * -> *) i.
(MArray a e m, Ix i) =>
a i e -> i -> e -> m ()
writeArray IOArray Int a
array Int
i a
x
     IOArray Int a -> Int -> a -> IO ()
forall (a :: * -> * -> *) e (m :: * -> *) i.
(MArray a e m, Ix i) =>
a i e -> i -> e -> m ()
writeArray IOArray Int a
array (Int
count Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) a
forall a. HasCallStack => a
undefined
     IORef Int -> Int -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef (Vector a -> IORef Int
forall a. Vector a -> IORef Int
vectorCountRef Vector a
vector) (Int
count Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)

-- | Delete the specified range of elements.
vectorDeleteRange :: Vector a
                     -- ^ the vector
                     -> Int
                     -- ^ the start index
                     -> Int
                     -- ^ the count of items to be removed
                     -> IO ()
vectorDeleteRange :: Vector a -> Int -> Int -> IO ()
vectorDeleteRange Vector a
vector Int
index Int
len =
  do Int
count <- IORef Int -> IO Int
forall a. IORef a -> IO a
readIORef (Vector a -> IORef Int
forall a. Vector a -> IORef Int
vectorCountRef Vector a
vector)
     Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Int
index Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$
       [Char] -> IO ()
forall a. HasCallStack => [Char] -> a
error ([Char] -> IO ()) -> [Char] -> IO ()
forall a b. (a -> b) -> a -> b
$
       [Char]
"The first index cannot be " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++
       [Char]
"negative: vectorDeleteRange."
     Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Int
index Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
len Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
count) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$
       [Char] -> IO ()
forall a. HasCallStack => [Char] -> a
error ([Char] -> IO ()) -> [Char] -> IO ()
forall a b. (a -> b) -> a -> b
$
       [Char]
"The last index must be less " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++
       [Char]
"than the count: vectorDeleteRange."
     Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Int
len Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$
       [Char] -> IO ()
forall a. HasCallStack => [Char] -> a
error [Char]
"Negative range length: vectorDeleteRange." 
     IOArray Int a
array <- IORef (IOArray Int a) -> IO (IOArray Int a)
forall a. IORef a -> IO a
readIORef (Vector a -> IORef (IOArray Int a)
forall a. Vector a -> IORef (IOArray Int a)
vectorArrayRef Vector a
vector)
     [Int] -> (Int -> IO ()) -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ [Int
index, Int
index Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1 .. (Int
count Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
len) Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1] ((Int -> IO ()) -> IO ()) -> (Int -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Int
i ->
       do a
x <- IOArray Int a -> Int -> IO a
forall (a :: * -> * -> *) e (m :: * -> *) i.
(MArray a e m, Ix i) =>
a i e -> i -> m e
readArray IOArray Int a
array (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
len)
          IOArray Int a -> Int -> a -> IO ()
forall (a :: * -> * -> *) e (m :: * -> *) i.
(MArray a e m, Ix i) =>
a i e -> i -> e -> m ()
writeArray IOArray Int a
array Int
i a
x
     [Int] -> (Int -> IO ()) -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ [(Int
count Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
len) .. Int
count Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1] ((Int -> IO ()) -> IO ()) -> (Int -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Int
i ->
       IOArray Int a -> Int -> a -> IO ()
forall (a :: * -> * -> *) e (m :: * -> *) i.
(MArray a e m, Ix i) =>
a i e -> i -> e -> m ()
writeArray IOArray Int a
array Int
i a
forall a. HasCallStack => a
undefined
     IORef Int -> Int -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef (Vector a -> IORef Int
forall a. Vector a -> IORef Int
vectorCountRef Vector a
vector) (Int
count Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
len)
     
-- | Return the index of the item or -1.     
vectorIndex :: Eq a => Vector a -> a -> IO Int
vectorIndex :: Vector a -> a -> IO Int
vectorIndex Vector a
vector a
item =
  do Int
count <- IORef Int -> IO Int
forall a. IORef a -> IO a
readIORef (Vector a -> IORef Int
forall a. Vector a -> IORef Int
vectorCountRef Vector a
vector)
     IOArray Int a
array <- IORef (IOArray Int a) -> IO (IOArray Int a)
forall a. IORef a -> IO a
readIORef (Vector a -> IORef (IOArray Int a)
forall a. Vector a -> IORef (IOArray Int a)
vectorArrayRef Vector a
vector)
     let loop :: Int -> m Int
loop Int
index =
           if Int
index Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
count
           then Int -> m Int
forall (m :: * -> *) a. Monad m => a -> m a
return (Int -> m Int) -> Int -> m Int
forall a b. (a -> b) -> a -> b
$ -Int
1
           else do a
x <- IOArray Int a -> Int -> m a
forall (a :: * -> * -> *) e (m :: * -> *) i.
(MArray a e m, Ix i) =>
a i e -> i -> m e
readArray IOArray Int a
array Int
index
                   if a
item a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
x
                     then Int -> m Int
forall (m :: * -> *) a. Monad m => a -> m a
return Int
index
                     else Int -> m Int
loop (Int -> m Int) -> Int -> m Int
forall a b. (a -> b) -> a -> b
$ Int
index Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1
     Int -> IO Int
forall (m :: * -> *). MArray IOArray a m => Int -> m Int
loop Int
0
     
-- | Return an index of the item satisfying the predicate or -1.     
vectorIndexBy :: Vector a -> (a -> Bool) -> IO Int
vectorIndexBy :: Vector a -> (a -> Bool) -> IO Int
vectorIndexBy Vector a
vector a -> Bool
pred =
  do Int
count <- IORef Int -> IO Int
forall a. IORef a -> IO a
readIORef (Vector a -> IORef Int
forall a. Vector a -> IORef Int
vectorCountRef Vector a
vector)
     IOArray Int a
array <- IORef (IOArray Int a) -> IO (IOArray Int a)
forall a. IORef a -> IO a
readIORef (Vector a -> IORef (IOArray Int a)
forall a. Vector a -> IORef (IOArray Int a)
vectorArrayRef Vector a
vector)
     let loop :: Int -> m Int
loop Int
index =
           if Int
index Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
count
           then Int -> m Int
forall (m :: * -> *) a. Monad m => a -> m a
return (Int -> m Int) -> Int -> m Int
forall a b. (a -> b) -> a -> b
$ -Int
1
           else do a
x <- IOArray Int a -> Int -> m a
forall (a :: * -> * -> *) e (m :: * -> *) i.
(MArray a e m, Ix i) =>
a i e -> i -> m e
readArray IOArray Int a
array Int
index
                   if a -> Bool
pred a
x
                     then Int -> m Int
forall (m :: * -> *) a. Monad m => a -> m a
return Int
index
                     else Int -> m Int
loop (Int -> m Int) -> Int -> m Int
forall a b. (a -> b) -> a -> b
$ Int
index Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1
     Int -> IO Int
forall (m :: * -> *). MArray IOArray a m => Int -> m Int
loop Int
0

-- | Remove the specified element and return a flag indicating
-- whether the element was found and removed.
vectorDelete :: Eq a => Vector a -> a -> IO Bool
vectorDelete :: Vector a -> a -> IO Bool
vectorDelete Vector a
vector a
item =
  do Int
index <- Vector a -> a -> IO Int
forall a. Eq a => Vector a -> a -> IO Int
vectorIndex Vector a
vector a
item
     if Int
index Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0
       then do Vector a -> Int -> IO ()
forall a. Vector a -> Int -> IO ()
vectorDeleteAt Vector a
vector Int
index
               Bool -> IO Bool
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True
       else Bool -> IO Bool
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
            
-- | Remove an element by the specified predicate and return the element if found.
vectorDeleteBy :: Vector a -> (a -> Bool) -> IO (Maybe a)
vectorDeleteBy :: Vector a -> (a -> Bool) -> IO (Maybe a)
vectorDeleteBy Vector a
vector a -> Bool
pred =
  do Int
index <- Vector a -> (a -> Bool) -> IO Int
forall a. Vector a -> (a -> Bool) -> IO Int
vectorIndexBy Vector a
vector a -> Bool
pred
     if Int
index Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0
       then do a
a <- Vector a -> Int -> IO a
forall a. Vector a -> Int -> IO a
readVector Vector a
vector Int
index
               Vector a -> Int -> IO ()
forall a. Vector a -> Int -> IO ()
vectorDeleteAt Vector a
vector Int
index
               Maybe a -> IO (Maybe a)
forall (m :: * -> *) a. Monad m => a -> m a
return (a -> Maybe a
forall a. a -> Maybe a
Just a
a)
       else Maybe a -> IO (Maybe a)
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe a
forall a. Maybe a
Nothing

-- | Detect whether the specified element is contained in the vector.
vectorContains :: Eq a => Vector a -> a -> IO Bool
vectorContains :: Vector a -> a -> IO Bool
vectorContains Vector a
vector a
item =
  do Int
index <- Vector a -> a -> IO Int
forall a. Eq a => Vector a -> a -> IO Int
vectorIndex Vector a
vector a
item
     Bool -> IO Bool
forall (m :: * -> *) a. Monad m => a -> m a
return (Int
index Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0)
            
-- | Detect whether an element satisfying the specified predicate is contained in the vector.
vectorContainsBy :: Vector a -> (a -> Bool) -> IO (Maybe a)
vectorContainsBy :: Vector a -> (a -> Bool) -> IO (Maybe a)
vectorContainsBy Vector a
vector a -> Bool
pred =
  do Int
index <- Vector a -> (a -> Bool) -> IO Int
forall a. Vector a -> (a -> Bool) -> IO Int
vectorIndexBy Vector a
vector a -> Bool
pred
     if Int
index Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0
       then do a
a <- Vector a -> Int -> IO a
forall a. Vector a -> Int -> IO a
readVector Vector a
vector Int
index
               Maybe a -> IO (Maybe a)
forall (m :: * -> *) a. Monad m => a -> m a
return (a -> Maybe a
forall a. a -> Maybe a
Just a
a)
       else Maybe a -> IO (Maybe a)
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe a
forall a. Maybe a
Nothing