repa-convert (empty) → 4.0.1.0
raw patch · 7 files changed
+910/−0 lines, 7 filesdep +basedep +primitivedep +vectorsetup-changed
Dependencies added: base, primitive, vector
Files
- Data/Repa/Convert/Format.hs +68/−0
- Data/Repa/Convert/Format/Base.hs +292/−0
- Data/Repa/Convert/Format/Binary.hs +330/−0
- Data/Repa/Product.hs +141/−0
- LICENSE +25/−0
- Setup.hs +2/−0
- repa-convert.cabal +52/−0
+ Data/Repa/Convert/Format.hs view
@@ -0,0 +1,68 @@++-- | Convert Haskell values to and from a compact binary representation.+-- +-- For testing purposes, use `packToList` which takes a format, a record, and returns a list of bytes.+--+-- @+-- > import Data.Repa.Convert.Format+--+-- > let Just bytes = packToList (FixString ASCII 10 :*: Word16be :*: Float64be) ("foo" :*: 66 :*: 93.42)+-- > bytes+-- [102,111,111,0,0,0,0,0,0,0,0,66,64,87,90,225,71,174,20,123]+-- @+--+-- We can then unpack the raw bytes back to Haskell values with `unpackFromList`.+--+-- @+-- > unpackFromList (FixString ASCII 10 :*: Word16be :*: Float64be) bytes +-- Just ("foo" :*: (66 :*: 93.42))+-- @+--+-- In production code use `pack` and `unpack` to work directly with a buffer in foreign memory.+--+module Data.Repa.Convert.Format+ ( -- * Data formats+ Format (..)++ -- * Packing records+ , Packable (..)+ , packToList+ , unpackFromList++ -- * Constraints+ , forFormat+ , listFormat++ -- * Products+ , (:*:)(..)++ -- * Lists+ , FixList(..)+ , VarList(..)++ -- * Strings+ , FixString (..)+ , VarString (..)+ , ASCII (..)++ -- * Atomic values+ -- ** 8-bit+ , Word8be (..), Int8be (..)++ -- ** 16-bit+ , Word16be (..), Int16be (..)++ -- ** 32-bit+ , Word32be (..), Int32be (..)+ , Float32be (..)++ -- ** 64-bit+ , Word64be (..), Int64be (..)+ , Float64be (..))++where+import Data.Repa.Product+import Data.Repa.Convert.Format.Base+import Data.Repa.Convert.Format.Binary++
+ Data/Repa/Convert/Format/Base.hs view
@@ -0,0 +1,292 @@++module Data.Repa.Convert.Format.Base+ ( Format (..)+ , Packable (..)+ , packToList+ , unpackFromList++ -- * Constraints+ , forFormat+ , listFormat++ -- * Strict products+ , (:*:)(..)++ -- * Lists+ , FixList(..)+ , VarList(..)++ -- * ASCII Strings+ , FixString (..)+ , VarString (..)+ , ASCII (..))++where+import Data.Repa.Product+import Data.Word+import Data.Char+import System.IO.Unsafe+import qualified Foreign.Storable as S+import qualified Foreign.Marshal.Alloc as S+import qualified Foreign.Ptr as S+++---------------------------------------------------------------------------------------------------+-- | Relates a storage format to the Haskell type of the value+-- that is stored in that format.+class Format f where++ -- | Get the type of a value with this format.+ type Value f ++ -- | For fixed size storage formats, yield their size (length) in bytes.+ --+ -- Yields `Nothing` if this is not a fixed size format.+ --+ fixedSize :: f -> Maybe Int++ -- | Yield the size of a value in the given format.+ --+ -- Yields `Nothing` when a collection of values is to be packed into a+ -- fixed length format, but the size of the collection does not match+ -- the format.+ --+ packedSize :: f -> Value f -> Maybe Int+++---------------------------------------------------------------------------------------------------+-- | Class of storage formats that can have values packed and unpacked+-- from foreign bufferes. +-- +-- The methods are written using continuations to make it easier for+-- GHC to optimise its core code when packing/unpacking many fields.+--+class Format format + => Packable format where++ -- | Pack a value into a buffer using the given format.+ -- + -- If the format contains fixed width fields and the corresponding+ -- value has too many elements, then this function returns `False`, + -- otherwise `True`.+ --+ pack :: S.Ptr Word8 -- ^ Target Buffer.+ -> format -- ^ Storage format.+ -> Value format -- ^ Value to pack.+ -> (Int -> IO (Maybe a)) -- ^ Continue, given the number of bytes written.+ -> IO (Maybe a)++ -- | Unpack a value from a buffer using the given format.+ --+ -- This is the inverse of `pack` above.+ unpack :: S.Ptr Word8 -- ^ Source buffer.+ -> format -- ^ Format of buffer.+ -> ((Value format, Int) -> IO (Maybe a)) + -- ^ Continue, given the unpacked value and the + -- number of bytes read. + -> IO (Maybe a)+++---------------------------------------------------------------------------------------------------+-- | Pack a value into a list of `Word8`.+packToList + :: Packable format+ => format -> Value format -> Maybe [Word8]+packToList f x+ | Just size <- packedSize f x+ = unsafePerformIO+ $ do buf <- S.mallocBytes size+ mResult <- pack buf f x (\_ -> return (Just ()))+ case mResult of+ Nothing -> return Nothing+ Just _ -> do+ xs <- mapM (S.peekByteOff buf) [0..size - 1]+ S.free buf+ return $ Just xs++ | otherwise+ = Nothing+++-- | Unpack a value from a list of `Word8`.+unpackFromList+ :: Packable format+ => format -> [Word8] -> Maybe (Value format)++unpackFromList f xs+ = unsafePerformIO+ $ do let len = length xs+ buf <- S.mallocBytes len+ mapM_ (\(o, x) -> S.pokeByteOff buf o x)+ $ zip [0 .. len - 1] xs+ unpack buf f $ \(v, _) -> return (Just v)+++---------------------------------------------------------------------------------------------------+-- | Constrain the type of a value to match the given format.+-- +-- The value itself is not used.+--+forFormat :: format -> Value format -> Value format+forFormat _ v = v+{-# INLINE forFormat #-}+++-- | Constrain the type of some values to match the given format.+--+-- The value itself is not used.+--+listFormat :: format -> [Value format] -> [Value format]+listFormat _ v = v+{-# INLINE listFormat #-}+++---------------------------------------------------------------------------------------------------+instance (Format a, Format b) + => Format (a :*: b) where+ type Value (a :*: b) = Value a :*: Value b++ fixedSize (xa :*: xb)+ = do sa <- fixedSize xa+ sb <- fixedSize xb+ return $ sa + sb+ {-# INLINE fixedSize #-}++ packedSize (fa :*: fb) (xa :*: xb)+ = do sa <- packedSize fa xa+ sb <- packedSize fb xb+ return $ sa + sb+ {-# INLINE packedSize #-}+++instance (Packable fa, Packable fb) + => Packable (fa :*: fb) where++ pack buf (fa :*: fb) (xa :*: xb) k+ = pack buf fa xa $ \oa + -> pack (S.plusPtr buf oa) fb xb $ \ob+ -> k (oa + ob)+ {-# INLINE pack #-}++ unpack buf (fa :*: fb) k+ = unpack buf fa $ \(xa, oa)+ -> unpack (S.plusPtr buf oa) fb $ \(xb, ob)+ -> k (xa :*: xb, oa + ob)+ {-# INLINE unpack #-}+++---------------------------------------------------------------------------------------------------+-- | Fixed length list.+--+data FixList f = FixList f Int deriving (Eq, Show)+instance Format f => Format (FixList f) where+ type Value (FixList f) = [Value f]++ fixedSize (FixList f len) + = do lenElem <- fixedSize f+ return $ lenElem * len++ packedSize (FixList _ 0) _+ = return 0++ packedSize (FixList f len) xs+ | length xs == len+ = do lenElems <- mapM (packedSize f) xs+ return $ sum lenElems++ | otherwise + = Nothing+++-- | Variable length list.+data VarList f = VarList f deriving (Eq, Show)+instance Format f => Format (VarList f) where+ type Value (VarList f) = [Value f]++ fixedSize (VarList _) = Nothing++ packedSize (VarList f) xs@(x : _)+ = do lenElem <- packedSize f x+ return $ lenElem * length xs++ packedSize _ []+ = return 0+++---------------------------------------------------------------------------------------------------+-- | Fixed length string.+-- +-- * When packing, if the provided string is shorter than the fixed length+-- then the extra bytes are zero-filled. +--+data FixString t = FixString t Int deriving (Eq, Show)+instance Format (FixString ASCII) where+ type Value (FixString ASCII) = String+ fixedSize (FixString ASCII len) = Just len+ packedSize (FixString ASCII len) _ = Just len+++instance Packable (FixString ASCII) where+ + pack buf (FixString ASCII lenField) xs k+ = do let !lenChars = length xs+ let !lenPad = lenField - lenChars++ if lenChars > lenField+ then return Nothing+ else do+ mapM_ (\(o, x) -> S.pokeByteOff buf o (w8 $ ord x)) + $ zip [0 .. lenChars - 1] xs++ mapM_ (\o -> S.pokeByteOff buf (lenChars + o) (0 :: Word8))+ $ [0 .. lenPad - 1]++ k lenField+ {-# NOINLINE pack #-}++ unpack buf (FixString ASCII lenField) k+ = do + let load_unpackChar o+ = do x :: Word8 <- S.peekByteOff buf o+ return $ chr $ fromIntegral x+ {-# INLINE load_unpackChar #-}++ xs <- mapM load_unpackChar [0 .. lenField - 1]+ let (pre, _) = break (== '\0') xs+ k (pre, lenField)+ {-# NOINLINE unpack #-}+++-- | Variable length string.+data VarString t = VarString t deriving (Eq, Show)+instance Format (VarString ASCII) where+ type Value (VarString ASCII) = String+ fixedSize (VarString ASCII) = Nothing+ packedSize (VarString ASCII) xs = Just $ length xs+++instance Packable (VarString ASCII) where++ pack buf (VarString ASCII) xs k+ = do let !lenChars = length xs++ mapM_ (\(o, x) -> S.pokeByteOff buf o (w8 $ ord x))+ $ zip [0 .. lenChars - 1] xs++ k lenChars+ {-# NOINLINE pack #-}++ unpack _ (VarString ASCII) _+ = return Nothing+ {-# NOINLINE unpack #-}+++-- | String is encoded as 8-bit ASCII characters.+data ASCII = ASCII deriving (Eq, Show)+++---------------------------------------------------------------------------------------------------+w8 :: Integral a => a -> Word8+w8 = fromIntegral+{-# INLINE w8 #-}+
+ Data/Repa/Convert/Format/Binary.hs view
@@ -0,0 +1,330 @@++-- | Atomic binary formats.+module Data.Repa.Convert.Format.Binary+ ( Format (..)++ , Word8be (..), Int8be (..)+ , Word16be (..), Int16be (..)+ , Word32be (..), Int32be (..)+ , Word64be (..), Int64be (..)++ , Float32be (..)+ , Float64be (..))+where+import Data.Repa.Convert.Format.Base+import Data.Bits +import Data.Int as V+import Data.Word as V+import qualified Foreign.Storable as S+import qualified Foreign.Marshal.Alloc as S+import qualified Foreign.Ptr as S+import qualified Control.Monad.Primitive as Prim+++------------------------------------------------------------------------------------------- Int8be+-- | Big-endian 8-bit signed integer.+data Int8be = Int8be deriving (Eq, Show)+instance Format Int8be where+ type Value Int8be = V.Int8+ fixedSize _ = Just 1+ packedSize _ _ = Just 1+++i8 :: Integral a => a -> Int8+i8 = fromIntegral+{-# INLINE i8 #-}+++------------------------------------------------------------------------------------------- Word8be+-- | Big-endian 8-bit unsigned word.+data Word8be = Word8be deriving (Eq, Show)+instance Format Word8be where+ type Value Word8be = V.Word8+ fixedSize _ = Just 1+ packedSize _ _ = Just 1+++instance Packable Word8be where+ pack buf Word8be x k+ = do S.poke buf (fromIntegral x)+ k 1+ {-# INLINE pack #-}++ unpack buf Word8be k+ = do x <- S.peek buf+ k (fromIntegral x, 1)+ {-# INLINE unpack #-}+++instance Packable Int8be where+ pack buf Int8be x k = pack buf Word8be (w8 x) k+ unpack buf Int8be k = unpack buf Word8be (\(x, o) -> k (i8 x, o))+ {-# INLINE pack #-}+ {-# INLINE unpack #-}+++w8 :: Integral a => a -> Word8+w8 = fromIntegral+{-# INLINE w8 #-}+++------------------------------------------------------------------------------------------- Int16be+--- | Big-endian 16-bit signed integer.+data Int16be = Int16be deriving (Eq, Show)+instance Format Int16be where+ type Value Int16be = V.Int16+ fixedSize _ = Just 2+ packedSize _ _ = Just 2++++i16 :: Integral a => a -> Int16+i16 = fromIntegral+{-# INLINE i16 #-}+++------------------------------------------------------------------------------------------ Word16be+-- | Big-endian 32-bit unsigned word.+data Word16be = Word16be deriving (Eq, Show)+instance Format Word16be where+ type Value Word16be = V.Word16+ fixedSize _ = Just 2+ packedSize _ _ = Just 2+++instance Packable Word16be where+ pack buf Word16be x k+ = do S.poke buf (w8 ((w16 x .&. 0x0ff00) `shiftR` 8))+ S.pokeByteOff buf 1 (w8 ((w16 x .&. 0x000ff)))+ k 2+ {-# INLINE pack #-}++ unpack buf Word16be k+ = do x0 :: Word8 <- S.peek buf + x1 :: Word8 <- S.peekByteOff buf 1+ let !x = w16 ((w16 x0 `shiftL` 8) .|. w16 x1)+ k (x, 2)+ {-# INLINE unpack #-}+++instance Packable Int16be where+ pack buf Int16be x k = pack buf Word16be (w16 x) k+ unpack buf Int16be k = unpack buf Word16be (\(x, o) -> k (i16 x, o))+ {-# INLINE pack #-}+ {-# INLINE unpack #-}+++w16 :: Integral a => a -> Word16+w16 = fromIntegral+{-# INLINE w16 #-}+++------------------------------------------------------------------------------------------- Int32be+-- | Big-endian 32-bit signed integer.+data Int32be = Int32be deriving (Eq, Show)+instance Format Int32be where+ type Value Int32be = V.Int32+ fixedSize _ = Just 4+ packedSize _ _ = Just 4+++instance Packable Int32be where+ pack buf Int32be x k = pack buf Word32be (w32 x) k+ unpack buf Int32be k = unpack buf Word32be (\(x, o) -> k (i32 x, o))+ {-# INLINE pack #-}+ {-# INLINE unpack #-}+++i32 :: Integral a => a -> Int32+i32 = fromIntegral+{-# INLINE i32 #-}+++------------------------------------------------------------------------------------------ Word32be+-- | Big-endian 32-bit unsigned word.+data Word32be = Word32be deriving (Eq, Show)+instance Format Word32be where+ type Value Word32be = V.Word32+ fixedSize _ = Just 4+ packedSize _ _ = Just 4+++instance Packable Word32be where+ pack buf Word32be x k+ = do S.poke buf (w8 ((w32 x .&. 0x0ff000000) `shiftR` 24))+ S.pokeByteOff buf 1 (w8 ((w32 x .&. 0x000ff0000) `shiftR` 16))+ S.pokeByteOff buf 2 (w8 ((w32 x .&. 0x00000ff00) `shiftR` 8))+ S.pokeByteOff buf 3 (w8 ((w32 x .&. 0x0000000ff)))+ k 4+ {-# INLINE pack #-}++ unpack buf Word32be k+ = do x0 :: Word8 <- S.peek buf + x1 :: Word8 <- S.peekByteOff buf 1+ x2 :: Word8 <- S.peekByteOff buf 2+ x3 :: Word8 <- S.peekByteOff buf 3+ let !x = w32 ( (w32 x0 `shiftL` 24) + .|. (w32 x1 `shiftL` 16)+ .|. (w32 x2 `shiftL` 8)+ .|. (w32 x3))+ k (x, 4)+ {-# INLINE unpack #-}+++w32 :: Integral a => a -> Word32+w32 = fromIntegral+{-# INLINE w32 #-}++------------------------------------------------------------------------------------------- Int64be+-- | Big-endian 64-bit signed integer.+data Int64be = Int64be deriving (Eq, Show)+instance Format Int64be where+ type Value Int64be = V.Int64+ fixedSize _ = Just 8+ packedSize _ _ = Just 8+++instance Packable Int64be where+ pack buf Int64be x k = pack buf Word64be (w64 x) k+ unpack buf Int64be k = unpack buf Word64be (\(x, o) -> k (i64 x, o))+ {-# INLINE pack #-}+ {-# INLINE unpack #-}+++i64 :: Integral a => a -> Int64+i64 = fromIntegral+{-# INLINE i64 #-}+++------------------------------------------------------------------------------------------ Word64be+-- | Big-endian 64-bit unsigned word.+data Word64be = Word64be deriving (Eq, Show)+instance Format Word64be where+ type Value Word64be = V.Word64+ fixedSize _ = Just 8+ packedSize _ _ = Just 8+++instance Packable Word64be where+ pack buf Word64be x k+ = do S.poke buf (w8 ((w64 x .&. 0x0ff00000000000000) `shiftR` 56))+ S.pokeByteOff buf 1 (w8 ((w64 x .&. 0x000ff000000000000) `shiftR` 48))+ S.pokeByteOff buf 2 (w8 ((w64 x .&. 0x00000ff0000000000) `shiftR` 40))+ S.pokeByteOff buf 3 (w8 ((w64 x .&. 0x0000000ff00000000) `shiftR` 32))+ S.pokeByteOff buf 4 (w8 ((w64 x .&. 0x000000000ff000000) `shiftR` 24))+ S.pokeByteOff buf 5 (w8 ((w64 x .&. 0x00000000000ff0000) `shiftR` 16))+ S.pokeByteOff buf 6 (w8 ((w64 x .&. 0x0000000000000ff00) `shiftR` 8))+ S.pokeByteOff buf 7 (w8 ((w64 x .&. 0x000000000000000ff) ))+ k 8+ {-# INLINE pack #-}++ unpack buf Word64be k+ = do x0 :: Word8 <- S.peek buf + x1 :: Word8 <- S.peekByteOff buf 1+ x2 :: Word8 <- S.peekByteOff buf 2+ x3 :: Word8 <- S.peekByteOff buf 3+ x4 :: Word8 <- S.peekByteOff buf 4+ x5 :: Word8 <- S.peekByteOff buf 5+ x6 :: Word8 <- S.peekByteOff buf 6+ x7 :: Word8 <- S.peekByteOff buf 7+ let !x = w64 ( (w64 x0 `shiftL` 56) + .|. (w64 x1 `shiftL` 48)+ .|. (w64 x2 `shiftL` 40)+ .|. (w64 x3 `shiftL` 32) + .|. (w64 x4 `shiftL` 24) + .|. (w64 x5 `shiftL` 16)+ .|. (w64 x6 `shiftL` 8)+ .|. (w64 x7 ))+ k (x, 8)+ {-# INLINE unpack #-}+++w64 :: Integral a => a -> Word64+w64 = fromIntegral+{-# INLINE w64 #-}+++----------------------------------------------------------------------------------------- Float32be+-- | Big-endian 32-bit IEEE 754 float.+data Float32be = Float32be deriving (Eq, Show)+instance Format Float32be where+ type Value Float32be = Float+ fixedSize _ = Just 4+ packedSize _ _ = Just 4+++instance Packable Float32be where+ pack buf Float32be x k+ = pack buf Word32be (floatToWord32 x) k+ {-# INLINE pack #-}++ unpack buf Float32be k+ = unpack buf Word32be (\(v, i) -> k (word32ToFloat v, i))+ {-# INLINE unpack #-}+++-- | Bitwise cast of `Float` to `Word32`.+--+-- The resulting `Word32` contains the representation of the `Float`, +-- rather than it's value.+floatToWord32 :: Float -> Word32+floatToWord32 d+ = Prim.unsafeInlineIO+ $ S.alloca $ \buf -> + do S.poke (S.castPtr buf) d+ S.peek buf+{-# INLINE floatToWord32 #-}+++-- | Inverse of `doubleToFloat32`+word32ToFloat :: Word32 -> Float+word32ToFloat w+ = Prim.unsafeInlineIO+ $ S.alloca $ \buf ->+ do S.poke (S.castPtr buf) w+ S.peek buf+{-# INLINE word32ToFloat #-}+++----------------------------------------------------------------------------------------- Float64be+-- | Big-endian 64-bit IEEE 754 float.+data Float64be = Float64be deriving (Eq, Show)+instance Format Float64be where+ type Value Float64be = Double+ fixedSize _ = Just 8+ packedSize _ _ = Just 8+++instance Packable Float64be where+ pack buf Float64be x k+ = pack buf Word64be (doubleToWord64 x) k+ {-# INLINE pack #-}++ unpack buf Float64be k+ = unpack buf Word64be (\(v, i) -> k (word64ToDouble v, i))+ {-# INLINE unpack #-}+++-- | Bitwise cast of `Double` to `Word64`.+--+-- The resulting `Word64` contains the representation of the `Double`, +-- rather than it's value.+doubleToWord64 :: Double -> Word64+doubleToWord64 d+ = Prim.unsafeInlineIO+ $ S.alloca $ \buf -> + do S.poke (S.castPtr buf) d+ S.peek buf+{-# INLINE doubleToWord64 #-}+++-- | Inverse of `doubleToWord64`+word64ToDouble :: Word64 -> Double+word64ToDouble w+ = Prim.unsafeInlineIO+ $ S.alloca $ \buf ->+ do S.poke (S.castPtr buf) w+ S.peek buf+{-# INLINE word64ToDouble #-}++
+ Data/Repa/Product.hs view
@@ -0,0 +1,141 @@++module Data.Repa.Product+ ((:*:)(..))+where+import qualified Data.Vector.Unboxed as U+import qualified Data.Vector.Generic as G+import qualified Data.Vector.Generic.Mutable as M++-- | Strict product type, written infix.+data a :*: b + = !a :*: !b + deriving (Eq, Show)++infixr :*:++-- Unboxed ----------------------------------------------------------------------------------------+-- Unboxed instance adapted from:+-- http://code.haskell.org/vector/internal/unbox-tuple-instances+--+data instance U.Vector (a :*: b)+ = V_Prod + {-# UNPACK #-} !Int + !(U.Vector a)+ !(U.Vector b)+++instance (U.Unbox a, U.Unbox b) + => U.Unbox (a :*: b)+++data instance U.MVector s (a :*: b)+ = MV_Prod {-# UNPACK #-} !Int + !(U.MVector s a)+ !(U.MVector s b)+++instance (U.Unbox a, U.Unbox b) + => M.MVector U.MVector (a :*: b) where++ basicLength (MV_Prod n_ _as _bs) = n_+ {-# INLINE basicLength #-}++ basicUnsafeSlice i_ m_ (MV_Prod _n_ as bs)+ = MV_Prod m_ (M.basicUnsafeSlice i_ m_ as)+ (M.basicUnsafeSlice i_ m_ bs)+ {-# INLINE basicUnsafeSlice #-}++ basicOverlaps (MV_Prod _n_1 as1 bs1) (MV_Prod _n_2 as2 bs2)+ = M.basicOverlaps as1 as2+ || M.basicOverlaps bs1 bs2+ {-# INLINE basicOverlaps #-}++ basicUnsafeNew n_+ = do as <- M.basicUnsafeNew n_+ bs <- M.basicUnsafeNew n_+ return $ MV_Prod n_ as bs+ {-# INLINE basicUnsafeNew #-}++ basicUnsafeReplicate n_ (a :*: b)+ = do as <- M.basicUnsafeReplicate n_ a+ bs <- M.basicUnsafeReplicate n_ b+ return $ MV_Prod n_ as bs+ {-# INLINE basicUnsafeReplicate #-}++ basicUnsafeRead (MV_Prod _n_ as bs) i_+ = do a <- M.basicUnsafeRead as i_+ b <- M.basicUnsafeRead bs i_+ return (a :*: b)+ {-# INLINE basicUnsafeRead #-}++ basicUnsafeWrite (MV_Prod _n_ as bs) i_ (a :*: b)+ = do M.basicUnsafeWrite as i_ a+ M.basicUnsafeWrite bs i_ b+ {-# INLINE basicUnsafeWrite #-}++ basicClear (MV_Prod _n_ as bs)+ = do M.basicClear as+ M.basicClear bs+ {-# INLINE basicClear #-}++ basicSet (MV_Prod _n_ as bs) (a :*: b)+ = do M.basicSet as a+ M.basicSet bs b+ {-# INLINE basicSet #-}++ basicUnsafeCopy (MV_Prod _n_1 as1 bs1) (MV_Prod _n_2 as2 bs2)+ = do M.basicUnsafeCopy as1 as2+ M.basicUnsafeCopy bs1 bs2+ {-# INLINE basicUnsafeCopy #-}++ basicUnsafeMove (MV_Prod _n_1 as1 bs1) (MV_Prod _n_2 as2 bs2)+ = do M.basicUnsafeMove as1 as2+ M.basicUnsafeMove bs1 bs2+ {-# INLINE basicUnsafeMove #-}++ basicUnsafeGrow (MV_Prod n_ as bs) m_+ = do as' <- M.basicUnsafeGrow as m_+ bs' <- M.basicUnsafeGrow bs m_+ return $ MV_Prod (m_ + n_) as' bs'+ {-# INLINE basicUnsafeGrow #-}+++instance (U.Unbox a, U.Unbox b) + => G.Vector U.Vector (a :*: b) where+ basicUnsafeFreeze (MV_Prod n_ as bs)+ = do as' <- G.basicUnsafeFreeze as+ bs' <- G.basicUnsafeFreeze bs+ return $ V_Prod n_ as' bs'+ {-# INLINE basicUnsafeFreeze #-}++ basicUnsafeThaw (V_Prod n_ as bs)+ = do as' <- G.basicUnsafeThaw as+ bs' <- G.basicUnsafeThaw bs+ return $ MV_Prod n_ as' bs'+ {-# INLINE basicUnsafeThaw #-}++ basicLength (V_Prod n_ _as _bs) + = n_+ {-# INLINE basicLength #-}++ basicUnsafeSlice i_ m_ (V_Prod _n_ as bs)+ = V_Prod m_ (G.basicUnsafeSlice i_ m_ as)+ (G.basicUnsafeSlice i_ m_ bs)+ {-# INLINE basicUnsafeSlice #-}++ basicUnsafeIndexM (V_Prod _n_ as bs) i_+ = do a <- G.basicUnsafeIndexM as i_+ b <- G.basicUnsafeIndexM bs i_+ return (a :*: b)+ {-# INLINE basicUnsafeIndexM #-}++ basicUnsafeCopy (MV_Prod _n_1 as1 bs1) (V_Prod _n_2 as2 bs2)+ = do G.basicUnsafeCopy as1 as2+ G.basicUnsafeCopy bs1 bs2+ {-# INLINE basicUnsafeCopy #-}++ elemseq _ (a :*: b)+ = G.elemseq (undefined :: U.Vector a) a+ . G.elemseq (undefined :: U.Vector b) b+ {-# INLINE elemseq #-}+
+ LICENSE view
@@ -0,0 +1,25 @@+Copyright (c) 2014-2015, The Repa Development Team++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++- Redistributions of source code must retain the above copyright notice,+ this list of conditions and the following disclaimer.++- Redistributions in binary form must reproduce the above copyright notice,+ this list of conditions and the following disclaimer in the documentation+ and/or other materials provided with the distribution.++- The names of the copyright holders may not be used to endorse or promote+ products derived from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE+COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ repa-convert.cabal view
@@ -0,0 +1,52 @@+Name: repa-convert+Version: 4.0.1.0+License: BSD3+License-file: LICENSE+Author: The Repa Development Team+Maintainer: Ben Lippmeier <benl@ouroborus.net>+Build-Type: Simple+Cabal-Version: >=1.6+Stability: experimental+Category: Data Structures+Homepage: http://repa.ouroborus.net+Bug-reports: repa@ouroborus.net+Description: Packing and unpacking binary data.+Synopsis: Packing and unpacking binary data.++source-repository head+ type: git+ location: https://github.com/DDCSF/repa.git++Library+ build-Depends: + base == 4.7.*,+ primitive == 0.5.4.*,+ vector == 0.10.*++ exposed-modules:+ Data.Repa.Product+ Data.Repa.Convert.Format++ other-modules:+ Data.Repa.Convert.Format.Base+ Data.Repa.Convert.Format.Binary++ ghc-options:+ -Wall -fno-warn-missing-signatures+ -O2++ extensions:+ CPP+ NoMonomorphismRestriction+ ExistentialQuantification+ BangPatterns+ FlexibleContexts+ FlexibleInstances+ PatternGuards+ MultiWayIf+ TypeFamilies+ TypeOperators+ ScopedTypeVariables+ MultiParamTypeClasses++