{-# LANGUAGE FlexibleContexts #-}

-- |
-- Module     : Simulation.Aivika.Vector.Unboxed
-- 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 unboxed vector.
--
module Simulation.Aivika.Vector.Unboxed
       (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

import Simulation.Aivika.Unboxed

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

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

-- | Copy the vector.
copyVector :: Unboxed a => Vector a -> IO (Vector a)
copyVector :: forall a. Unboxed a => Vector a -> IO (Vector a)
copyVector Vector a
vector =
  do IOUArray Int a
array <- forall a. IORef a -> IO a
readIORef (forall a. Vector a -> IORef (IOUArray Int a)
vectorArrayRef Vector a
vector)
     Int
count <- forall a. IORef a -> IO a
readIORef (forall a. Vector a -> IORef Int
vectorCountRef Vector a
vector)
     IOUArray Int a
array' <- forall e i. (Unboxed e, Ix i) => (i, i) -> IO (IOUArray i e)
newUnboxedArray_ (Int
0, Int
count forall a. Num a => a -> a -> a
- Int
1)
     IORef (IOUArray Int a)
arrayRef' <- forall a. a -> IO (IORef a)
newIORef IOUArray Int a
array'
     IORef Int
countRef' <- forall a. a -> IO (IORef a)
newIORef Int
count
     IORef Int
capacityRef' <- forall a. a -> IO (IORef a)
newIORef Int
count
     forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ [Int
0 .. Int
count forall a. Num a => a -> a -> a
- Int
1] forall a b. (a -> b) -> a -> b
$ \Int
i ->
       do a
x <- forall (a :: * -> * -> *) e (m :: * -> *) i.
(MArray a e m, Ix i) =>
a i e -> i -> m e
readArray IOUArray Int a
array Int
i
          forall (a :: * -> * -> *) e (m :: * -> *) i.
(MArray a e m, Ix i) =>
a i e -> i -> e -> m ()
writeArray IOUArray Int a
array' Int
i a
x
     forall (m :: * -> *) a. Monad m => a -> m a
return Vector { vectorArrayRef :: IORef (IOUArray Int a)
vectorArrayRef = IORef (IOUArray 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 :: Unboxed a => Vector a -> Int -> IO ()
vectorEnsureCapacity :: forall a. Unboxed a => Vector a -> Int -> IO ()
vectorEnsureCapacity Vector a
vector Int
capacity =
  do Int
capacity' <- forall a. IORef a -> IO a
readIORef (forall a. Vector a -> IORef Int
vectorCapacityRef Vector a
vector)
     forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Int
capacity' forall a. Ord a => a -> a -> Bool
< Int
capacity) forall a b. (a -> b) -> a -> b
$
       do IOUArray Int a
array' <- forall a. IORef a -> IO a
readIORef (forall a. Vector a -> IORef (IOUArray Int a)
vectorArrayRef Vector a
vector)
          Int
count' <- forall a. IORef a -> IO a
readIORef (forall a. Vector a -> IORef Int
vectorCountRef Vector a
vector)
          let capacity'' :: Int
capacity'' = forall a. Ord a => a -> a -> a
max (Int
2 forall a. Num a => a -> a -> a
* Int
capacity') Int
capacity
          IOUArray Int a
array'' <- forall e i. (Unboxed e, Ix i) => (i, i) -> IO (IOUArray i e)
newUnboxedArray_ (Int
0, Int
capacity'' forall a. Num a => a -> a -> a
- Int
1)
          forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ [Int
0 .. Int
count' forall a. Num a => a -> a -> a
- Int
1] forall a b. (a -> b) -> a -> b
$ \Int
i ->
            do a
x <- forall (a :: * -> * -> *) e (m :: * -> *) i.
(MArray a e m, Ix i) =>
a i e -> i -> m e
readArray IOUArray Int a
array' Int
i
               forall (a :: * -> * -> *) e (m :: * -> *) i.
(MArray a e m, Ix i) =>
a i e -> i -> e -> m ()
writeArray IOUArray Int a
array'' Int
i a
x
          forall a. IORef a -> a -> IO ()
writeIORef (forall a. Vector a -> IORef (IOUArray Int a)
vectorArrayRef Vector a
vector) IOUArray Int a
array''
          forall a. IORef a -> a -> IO ()
writeIORef (forall a. Vector a -> IORef Int
vectorCapacityRef Vector a
vector) Int
capacity''
          
-- | Return the element count.
vectorCount :: Unboxed a => Vector a -> IO Int
vectorCount :: forall a. Unboxed a => Vector a -> IO Int
vectorCount Vector a
vector = forall a. IORef a -> IO a
readIORef (forall a. Vector a -> IORef Int
vectorCountRef Vector a
vector)
          
-- | Add the specified element to the end of the vector.
appendVector :: Unboxed a => Vector a -> a -> IO ()          
appendVector :: forall a. Unboxed a => Vector a -> a -> IO ()
appendVector Vector a
vector a
item =
  do Int
count <- forall a. IORef a -> IO a
readIORef (forall a. Vector a -> IORef Int
vectorCountRef Vector a
vector)
     forall a. Unboxed a => Vector a -> Int -> IO ()
vectorEnsureCapacity Vector a
vector (Int
count forall a. Num a => a -> a -> a
+ Int
1)
     IOUArray Int a
array <- forall a. IORef a -> IO a
readIORef (forall a. Vector a -> IORef (IOUArray Int a)
vectorArrayRef Vector a
vector)
     forall (a :: * -> * -> *) e (m :: * -> *) i.
(MArray a e m, Ix i) =>
a i e -> i -> e -> m ()
writeArray IOUArray Int a
array Int
count a
item
     forall a. IORef a -> a -> IO ()
writeIORef (forall a. Vector a -> IORef Int
vectorCountRef Vector a
vector) (Int
count forall a. Num a => a -> a -> a
+ Int
1)
     
-- | Read a value from the vector, where indices are started from 0.
readVector :: Unboxed a => Vector a -> Int -> IO a
readVector :: forall a. Unboxed a => Vector a -> Int -> IO a
readVector Vector a
vector Int
index =
  do IOUArray Int a
array <- forall a. IORef a -> IO a
readIORef (forall a. Vector a -> IORef (IOUArray Int a)
vectorArrayRef Vector a
vector)
     forall (a :: * -> * -> *) e (m :: * -> *) i.
(MArray a e m, Ix i) =>
a i e -> i -> m e
readArray IOUArray Int a
array Int
index
          
-- | Set an array item at the specified index which is started from 0.
writeVector :: Unboxed a => Vector a -> Int -> a -> IO ()
writeVector :: forall a. Unboxed a => Vector a -> Int -> a -> IO ()
writeVector Vector a
vector Int
index a
item =
  do IOUArray Int a
array <- forall a. IORef a -> IO a
readIORef (forall a. Vector a -> IORef (IOUArray Int a)
vectorArrayRef Vector a
vector)
     forall (a :: * -> * -> *) e (m :: * -> *) i.
(MArray a e m, Ix i) =>
a i e -> i -> e -> m ()
writeArray IOUArray Int a
array Int
index a
item
          
vectorBinarySearch' :: (Unboxed a, Ord a) => IOUArray Int a -> a -> Int -> Int -> IO Int
vectorBinarySearch' :: forall a.
(Unboxed a, Ord a) =>
IOUArray Int a -> a -> Int -> Int -> IO Int
vectorBinarySearch' IOUArray Int a
array a
item Int
left Int
right =
  if Int
left forall a. Ord a => a -> a -> Bool
> Int
right 
  then forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ - (Int
right forall a. Num a => a -> a -> a
+ Int
1) forall a. Num a => a -> a -> a
- Int
1
  else
    do let index :: Int
index = (Int
left forall a. Num a => a -> a -> a
+ Int
right) forall a. Integral a => a -> a -> a
`div` Int
2
       a
curr <- forall (a :: * -> * -> *) e (m :: * -> *) i.
(MArray a e m, Ix i) =>
a i e -> i -> m e
readArray IOUArray Int a
array Int
index
       if a
item forall a. Ord a => a -> a -> Bool
< a
curr 
         then forall a.
(Unboxed a, Ord a) =>
IOUArray Int a -> a -> Int -> Int -> IO Int
vectorBinarySearch' IOUArray Int a
array a
item Int
left (Int
index forall a. Num a => a -> a -> a
- Int
1)
         else if a
item forall a. Eq a => a -> a -> Bool
== a
curr
              then forall (m :: * -> *) a. Monad m => a -> m a
return Int
index
              else forall a.
(Unboxed a, Ord a) =>
IOUArray Int a -> a -> Int -> Int -> IO Int
vectorBinarySearch' IOUArray Int a
array a
item (Int
index 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 :: (Unboxed a, Ord a) => Vector a -> a -> IO Int
vectorBinarySearch :: forall a. (Unboxed a, Ord a) => Vector a -> a -> IO Int
vectorBinarySearch Vector a
vector a
item =
  do IOUArray Int a
array <- forall a. IORef a -> IO a
readIORef (forall a. Vector a -> IORef (IOUArray Int a)
vectorArrayRef Vector a
vector)
     Int
count <- forall a. IORef a -> IO a
readIORef (forall a. Vector a -> IORef Int
vectorCountRef Vector a
vector)
     forall a.
(Unboxed a, Ord a) =>
IOUArray Int a -> a -> Int -> Int -> IO Int
vectorBinarySearch' IOUArray Int a
array a
item Int
0 (Int
count forall a. Num a => a -> a -> a
- Int
1)

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

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

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