module Sym.Internal.CLongArray
(
CLongArray
, fromList
, toList
, slices
, size
, at
, unsafeAt
, elemIndices
, imap
, izipWith
, unsafeNew
, unsafeWith
) where
import Data.Ord
import qualified Data.Vector.Storable as V
import qualified Data.Vector.Storable.Mutable as MV
import Sym.Internal.Size
import Foreign
import Foreign.C.Types
infixl 9 `at`
infixl 9 `unsafeAt`
newtype CLongArray = CArr (V.Vector CLong) deriving (Eq)
instance Ord CLongArray where
compare u v =
case comparing size u v of
EQ -> comparing toList u v
x -> x
instance Size CLongArray where
size (CArr w) = V.length w
instance Show CLongArray where
show w = "fromList " ++ show (toList w)
fromList :: [Int] -> CLongArray
fromList = CArr . V.fromList . map fromIntegral
toList :: CLongArray -> [Int]
toList (CArr w) = map fromIntegral $ V.toList w
slices :: [Int] -> CLongArray -> [CLongArray]
slices [] _ = []
slices (k:ks) (CArr w) = let (u,v) = V.splitAt k w in CArr u : slices ks (CArr v)
at :: CLongArray -> Int -> Int
at (CArr w) i =
case (V.!?) w i of
Nothing -> error "Sym.Internal.CLongArray.at: out of range"
Just j -> fromIntegral j
unsafeAt :: CLongArray -> Int -> Int
unsafeAt (CArr w) = fromIntegral . (V.!) w
elemIndices :: CLong -> CLongArray -> V.Vector Int
elemIndices x (CArr w) = V.elemIndices x w
imap :: (Int -> CLong -> CLong) -> CLongArray -> CLongArray
imap f (CArr w) = CArr (V.imap f w)
izipWith :: (Int -> CLong -> CLong -> CLong) -> CLongArray -> CLongArray -> CLongArray
izipWith f (CArr u) (CArr v) = CArr (V.izipWith f u v)
unsafeNew :: Int -> (Ptr CLong -> IO ()) -> IO CLongArray
unsafeNew n act = do
v <- V.unsafeFreeze =<< MV.unsafeNew n
let (ptr, _) = V.unsafeToForeignPtr0 v
withForeignPtr ptr act
return $ CArr (V.unsafeFromForeignPtr0 ptr n)
unsafeWith :: CLongArray -> (Ptr CLong -> IO a) -> IO a
unsafeWith (CArr w) = V.unsafeWith w