Last active
September 15, 2018 04:20
-
-
Save chpatrick/bd1569f6f3e322aa1423 to your computer and use it in GitHub Desktop.
Baked-in Storable Vectors Mark II
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{-# LANGUAGE MagicHash, TupleSections, TemplateHaskell #-} | |
module Data.Vector.Storable.Bake(bake, unsafeFromAddrLen) where | |
import Data.Typeable | |
import qualified Data.Vector.Storable as VS | |
import Foreign | |
import GHC.Prim | |
import GHC.Ptr | |
import Language.Haskell.TH | |
import Language.Haskell.TH.Syntax | |
import System.IO.Unsafe | |
-- | Bakes a given `Vector` into the binary. | |
bake :: (Storable a, Typeable a) => VS.Vector a -> Q Exp | |
bake xs = [|unsafeFromAddrLen $(str) $(len) :: VS.Vector $(a)|] | |
where | |
str = litE $ StringPrimL $ VS.toList $ VS.unsafeCast xs | |
len = lift $ VS.length xs | |
a = conT $ typeRepToName $ typeRep xs | |
-- | Make a `Storable` `VS.Vector` from an `Addr#` and a length. Very unsafe. | |
unsafeFromAddrLen :: Storable a => Addr# -> Int -> VS.Vector a | |
unsafeFromAddrLen addr | |
= VS.unsafeFromForeignPtr0 (unsafePerformIO (newForeignPtr_ (Ptr addr))) | |
-- | Convert a `TypeRep` to a Template Haskell `Name`. | |
typeRepToName :: TypeRep -> Name | |
typeRepToName rep | |
= Name (mkOccName $ tyConName tc) $ | |
NameG TcClsName | |
(mkPkgName $ tyConPackage tc) | |
(mkModName $ tyConModule tc) | |
where tc = typeRepTyCon rep |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment