vector-endian-0.1.0.0: src/vector-endian-indef/Internal/Vector.hs
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}
module Internal.Vector where
import Zhp hiding (empty)
import Data.Vector.Endian.Class (Endian)
import Internal.Endianness (from, to)
import Text.Read (Read(..))
import Control.DeepSeq (NFData)
import Control.Monad.ST (ST)
import Data.Traversable (Traversable)
import Data.Vector.Storable (Storable)
import Foreign.ForeignPtr (ForeignPtr)
import Foreign.Ptr (Ptr)
import GHC.Exts (IsList(..))
import qualified Data.Vector.Generic as GV
import qualified Data.Vector.Generic.Mutable as GMV
import qualified Data.Vector.Storable as SV
import qualified Data.Vector.Storable.Mutable as SMV
newtype MVector s a = MVector (SMV.MVector s a)
deriving(NFData)
newtype Vector a = Vector (SV.Vector a)
deriving(Eq, NFData, Semigroup, Monoid)
instance (Storable a, Endian a) => IsList (Vector a) where
type Item (Vector a) = a
fromList = Vector . fromList . map to
fromListN len = Vector . fromListN len . map to
toList (Vector v) = map from $ SV.toList v
instance (Show a, SV.Storable a, Endian a) => Show (Vector a) where
show (Vector v) = show $ SV.map from v
instance (Read a, SV.Storable a, Endian a) => Read (Vector a) where
-- Read in the storable vector, then convert all of the elemnents to
-- the storage format we need.
readPrec = Vector . SV.map to <$> readPrec
type instance GV.Mutable Vector = MVector
instance (SV.Storable a, Endian a) => GMV.MVector MVector a where
-- These are all trivial wrappers around the underlying vector.
basicLength (MVector v) = GMV.basicLength v
basicUnsafeSlice i len (MVector v) = MVector (GMV.basicUnsafeSlice i len v)
basicOverlaps (MVector l) (MVector r) = GMV.basicOverlaps l r
basicUnsafeNew = fmap MVector . GMV.basicUnsafeNew
basicInitialize (MVector v) = GMV.basicInitialize v
basicClear (MVector v) = GMV.basicClear v
basicUnsafeCopy (MVector l) (MVector r) = GMV.basicUnsafeCopy l r
basicUnsafeMove (MVector l) (MVector r) = GMV.basicUnsafeMove l r
basicUnsafeGrow (MVector v) i = MVector <$> GMV.basicUnsafeGrow v i
-- These have to do endianness conversion:
basicUnsafeReplicate !i !e = GMV.basicUnsafeReplicate i $! to e
basicUnsafeRead (MVector v) i = from <$> GMV.basicUnsafeRead v i
basicUnsafeWrite (MVector v) i e = GMV.basicUnsafeWrite v i $! to e
basicSet (MVector v) e = GMV.basicSet v $! to e
instance (SV.Storable a, Endian a) => GV.Vector Vector a where
-- boring wrappers:
basicUnsafeFreeze (MVector v) = Vector <$> GV.basicUnsafeFreeze v
basicUnsafeThaw (Vector v) = MVector <$> GV.basicUnsafeThaw v
basicLength (Vector v) = GV.basicLength v
basicUnsafeSlice i len (Vector v) = Vector (GV.basicUnsafeSlice i len v)
basicUnsafeCopy (MVector mv) (Vector v) = GV.basicUnsafeCopy mv v
elemseq (Vector v) x y = GV.elemseq v x y
-- need to do endianness conversion:
basicUnsafeIndexM (Vector v) i = from <$!> GV.basicUnsafeIndexM v i
---------------
-- Accessors --
---------------
-- Length information
---------------------
length :: (Storable a, Endian a) => Vector a -> Int
length (Vector v) = SV.length v
null :: (Storable a, Endian a) => Vector a -> Bool
null (Vector v) = SV.null v
-- Indexing
-----------
(!) :: (Storable a, Endian a) => Vector a -> Int -> a
(!) (Vector v) i = from $! v SV.! i
(!?) :: (Storable a, Endian a) => Vector a -> Int -> Maybe a
Vector v !? i = from <$!> v SV.!? i
head :: (Storable a, Endian a) => Vector a -> a
head (Vector v) = from $! SV.head v
last :: (Storable a, Endian a) => Vector a -> a
last (Vector v) = from $! SV.last v
unsafeIndex :: (Storable a, Endian a) => Vector a -> Int -> a
unsafeIndex (Vector v) i = from $! SV.unsafeIndex v i
unsafeHead :: (Storable a, Endian a) => Vector a -> a
unsafeHead (Vector v) = from $! SV.unsafeHead v
unsafeLast :: (Storable a, Endian a) => Vector a -> a
unsafeLast (Vector v) = from $! SV.unsafeLast v
-- Monadic indexing
-------------------
indexM :: (Storable a, Endian a, Monad m) => Vector a -> Int -> m a
indexM (Vector v) i = from <$!> SV.indexM v i
headM :: (Storable a, Endian a, Monad m) => Vector a -> m a
headM (Vector v) = from <$!> SV.headM v
lastM :: (Storable a, Endian a, Monad m) => Vector a -> m a
lastM (Vector v) = from <$!> SV.lastM v
unsafeIndexM :: (Storable a, Endian a, Monad m) => Vector a -> Int -> m a
unsafeIndexM (Vector v) i = from <$!> SV.unsafeIndexM v i
unsafeHeadM :: (Storable a, Endian a, Monad m) => Vector a -> m a
unsafeHeadM (Vector v) = from <$!> SV.unsafeHeadM v
unsafeLastM :: (Storable a, Endian a, Monad m) => Vector a -> m a
unsafeLastM (Vector v) = from <$!> SV.unsafeLastM v
-- Extracting subvectors (slicing)
----------------------------------
slice :: (Storable a, Endian a) => Int -> Int -> Vector a -> Vector a
slice i len (Vector v) = Vector (SV.slice i len v)
init :: (Storable a, Endian a) => Vector a -> Vector a
init (Vector v) = Vector (SV.init v)
tail :: (Storable a, Endian a) => Vector a -> Vector a
tail (Vector v) = Vector (SV.tail v)
take :: (Storable a, Endian a) => Int -> Vector a -> Vector a
take count (Vector v) = Vector (SV.take count v)
drop :: (Storable a, Endian a) => Int -> Vector a -> Vector a
drop count (Vector v) = Vector (SV.drop count v)
splitAt :: (Storable a, Endian a) => Int -> Vector a -> (Vector a, Vector a)
splitAt i (Vector v) =
let (l, r) = SV.splitAt i v
in (Vector l, Vector r)
unsafeSlice :: (Storable a, Endian a) => Int -> Int -> Vector a -> Vector a
unsafeSlice i len (Vector v) = Vector (SV.unsafeSlice i len v)
unsafeInit :: (Storable a, Endian a) => Vector a -> Vector a
unsafeInit (Vector v) = Vector (SV.unsafeInit v)
unsafeTail :: (Storable a, Endian a) => Vector a -> Vector a
unsafeTail (Vector v) = Vector (SV.unsafeTail v)
unsafeTake :: (Storable a, Endian a) => Int -> Vector a -> Vector a
unsafeTake count (Vector v) = Vector (SV.unsafeTake count v)
unsafeDrop :: (Storable a, Endian a) => Int -> Vector a -> Vector a
unsafeDrop count (Vector v) = Vector (SV.unsafeDrop count v)
---------------
-- Construction
---------------
-- Initialisation
-----------------
empty :: (Storable a, Endian a) => Vector a
empty = Vector SV.empty
singleton :: (Storable a, Endian a) => a -> Vector a
singleton value = Vector (SV.singleton (to value))
replicate :: (Storable a, Endian a) => Int -> a -> Vector a
replicate count value = Vector (SV.replicate count (to value))
generate :: (Storable a, Endian a) => Int -> (Int -> a) -> Vector a
generate count f = Vector (SV.generate count (to . f))
iterateN :: (Storable a, Endian a) => Int -> (a -> a) -> a -> Vector a
iterateN count f orig = Vector (SV.iterateN count (to . f . from) (to orig))
-- Monadic Initialisation
-------------------------
replicateM :: (Monad m, Storable a, Endian a) => Int -> m a -> m (Vector a)
replicateM count m = Vector <$> SV.replicateM count (to <$> m)
generateM :: (Monad m, Storable a, Endian a) => Int -> (Int -> m a) -> m (Vector a)
generateM count m = Vector <$> SV.generateM count (fmap to . m)
iterateNM :: (Monad m, Storable a, Endian a) => Int -> (a -> m a) -> a -> m (Vector a)
iterateNM count m orig = Vector <$> SV.iterateNM count (fmap to . m . from) orig
create :: (Storable a, Endian a) => (forall s. ST s (MVector s a)) -> Vector a
create = GV.create
createT :: (Traversable f, Storable a, Endian a)
=> (forall s. ST s (f (MVector s a))) -> f (Vector a)
createT = GV.createT
-- Unfolding
------------
unfoldr :: (Storable a, Endian a) => (b -> Maybe (a, b)) -> b -> Vector a
unfoldr = GV.unfoldr
unfoldrN :: (Storable a, Endian a) => Int -> (b -> Maybe (a, b)) -> b -> Vector a
unfoldrN = GV.unfoldrN
unfoldrM :: (Monad m, Storable a, Endian a) => (b -> m (Maybe (a, b))) -> b -> m (Vector a)
unfoldrM = GV.unfoldrM
unfoldrNM :: (Monad m, Storable a, Endian a) => Int -> (b -> m (Maybe (a, b))) -> b -> m (Vector a)
unfoldrNM = GV.unfoldrNM
constructN :: (Storable a, Endian a) => Int -> (Vector a -> a) -> Vector a
constructN = GV.constructN
constructrN :: (Storable a, Endian a) => Int -> (Vector a -> a) -> Vector a
constructrN = GV.constructrN
-- Enumeration
--------------
enumFromN :: (Storable a, Endian a, Num a) => a -> Int -> Vector a
enumFromN = GV.enumFromN
enumFromStepN :: (Storable a, Endian a, Num a) => a -> a -> Int -> Vector a
enumFromStepN = GV.enumFromStepN
enumFromTo :: (Storable a, Endian a, Enum a) => a -> a -> Vector a
enumFromTo = GV.enumFromTo
enumFromThenTo :: (Storable a, Endian a, Enum a) => a -> a -> a -> Vector a
enumFromThenTo = GV.enumFromThenTo
---------------
-- Raw pointers
---------------
unsafeFromForeignPtr :: (SV.Storable a, Endian a)
=> ForeignPtr a -> Int -> Int -> Vector a
unsafeFromForeignPtr p off len = Vector $ SV.unsafeFromForeignPtr p off len
unsafeFromForeignPtr0 :: (SV.Storable a, Endian a)
=> ForeignPtr a -> Int -> Vector a
unsafeFromForeignPtr0 p len = Vector $ SV.unsafeFromForeignPtr0 p len
unsafeToForeignPtr :: (SV.Storable a, Endian a)
=> Vector a -> (ForeignPtr a, Int, Int)
unsafeToForeignPtr (Vector v) = SV.unsafeToForeignPtr v
unsafeToForeignPtr0 :: (SV.Storable a, Endian a)
=> Vector a -> (ForeignPtr a, Int)
unsafeToForeignPtr0 (Vector v) = SV.unsafeToForeignPtr0 v
-- | Like 'SV.unsafeWith', but note well: the pointer will point to the value
-- in its *wire format*, which may not match the host cpu endianness.
unsafeWith :: (SV.Storable a, Endian a) => Vector a -> (Ptr a -> IO b) -> IO b
unsafeWith (Vector v) = SV.unsafeWith v