1{-# OPTIONS_GHC -fno-warn-orphans #-}
3{-# LANGUAGE BangPatterns #-}
5{-# LANGUAGE KindSignatures #-}
6{-# LANGUAGE MagicHash #-}
7{-# LANGUAGE MultiParamTypeClasses #-}
8{-# LANGUAGE PolyKinds #-}
9{-# LANGUAGE TypeFamilies #-}
11module Data.TypeRep.Vector
21import Prelude hiding (lookup)
23import Control.Arrow ((&&&))
24import Data.Proxy (Proxy (..))
25import Data.Typeable (Typeable, typeRep, typeRepFingerprint)
26import Data.Word (Word64)
27import GHC.Base hiding (empty)
28import GHC.Exts (sortWith)
29import GHC.Fingerprint (Fingerprint (..))
30import Unsafe.Coerce (unsafeCoerce)
32import qualified Data.Vector as V
33import qualified Data.Vector.Generic as G
34import qualified Data.Vector.Generic.Mutable as M
35import qualified Data.Vector.Unboxed as Unboxed
37data instance Unboxed.MVector s Fingerprint = MFingerprintVector (Unboxed.MVector s Word64) (Unboxed.MVector s Word64)
38data instance Unboxed.Vector Fingerprint = FingerprintVector (Unboxed.Vector Word64) (Unboxed.Vector Word64)
40instance Unboxed.Unbox Fingerprint
42instance M.MVector Unboxed.MVector Fingerprint where
43 {-# INLINE basicLength #-}
44 basicLength (MFingerprintVector x _) = M.basicLength x
45 {-# INLINE basicUnsafeSlice #-}
46 basicUnsafeSlice i m (MFingerprintVector a b) =
47 MFingerprintVector (M.basicUnsafeSlice i m a) (M.basicUnsafeSlice i m b)
48 {-# INLINE basicOverlaps #-}
49 basicOverlaps (MFingerprintVector as1 bs1) (MFingerprintVector as2 bs2) =
50 M.basicOverlaps as1 as2 || M.basicOverlaps bs1 bs2
51 {-# INLINE basicUnsafeNew #-}
52 basicUnsafeNew n_ = do
53 as <- M.basicUnsafeNew n_
54 bs <- M.basicUnsafeNew n_
55 return $ MFingerprintVector as bs
56 {-# INLINE basicInitialize #-}
57 basicInitialize (MFingerprintVector as bs) = do
60 {-# INLINE basicUnsafeReplicate #-}
61 basicUnsafeReplicate n_ (Fingerprint a b) = do
62 as <- M.basicUnsafeReplicate n_ a
63 bs <- M.basicUnsafeReplicate n_ b
64 return $ MFingerprintVector as bs
65 {-# INLINE basicUnsafeRead #-}
66 basicUnsafeRead (MFingerprintVector as bs) i_ = do
67 a <- M.basicUnsafeRead as i_
68 b <- M.basicUnsafeRead bs i_
69 return (Fingerprint a b)
70 {-# INLINE basicUnsafeWrite #-}
71 basicUnsafeWrite (MFingerprintVector as bs) i_ (Fingerprint a b) = do
72 M.basicUnsafeWrite as i_ a
73 M.basicUnsafeWrite bs i_ b
74 {-# INLINE basicClear #-}
75 basicClear (MFingerprintVector as bs) = do
78 {-# INLINE basicSet #-}
79 basicSet (MFingerprintVector as bs) (Fingerprint a b) = do
82 {-# INLINE basicUnsafeCopy #-}
83 basicUnsafeCopy (MFingerprintVector as1 bs1) (MFingerprintVector as2 bs2) = do
84 M.basicUnsafeCopy as1 as2
85 M.basicUnsafeCopy bs1 bs2
86 {-# INLINE basicUnsafeMove #-}
87 basicUnsafeMove (MFingerprintVector as1 bs1) (MFingerprintVector as2 bs2) = do
88 M.basicUnsafeMove as1 as2
89 M.basicUnsafeMove bs1 bs2
90 {-# INLINE basicUnsafeGrow #-}
91 basicUnsafeGrow (MFingerprintVector as bs) m_ = do
92 as' <- M.basicUnsafeGrow as m_
93 bs' <- M.basicUnsafeGrow bs m_
94 return $ MFingerprintVector as' bs'
96instance G.Vector Unboxed.Vector Fingerprint where
97 {-# INLINE basicUnsafeFreeze #-}
98 basicUnsafeFreeze (MFingerprintVector as bs) = do
99 as' <- G.basicUnsafeFreeze as
100 bs' <- G.basicUnsafeFreeze bs
101 return $ FingerprintVector as' bs'
102 {-# INLINE basicUnsafeThaw #-}
103 basicUnsafeThaw (FingerprintVector as bs) = do
104 as' <- G.basicUnsafeThaw as
105 bs' <- G.basicUnsafeThaw bs
106 return $ MFingerprintVector as' bs'
107 {-# INLINE basicLength #-}
108 basicLength (FingerprintVector x _) = G.basicLength x
109 {-# INLINE basicUnsafeSlice #-}
110 basicUnsafeSlice i_ m_ (FingerprintVector as bs) =
111 FingerprintVector (G.basicUnsafeSlice i_ m_ as) (G.basicUnsafeSlice i_ m_ bs)
112 {-# INLINE basicUnsafeIndexM #-}
113 basicUnsafeIndexM (FingerprintVector as bs) i_ = do
114 a <- G.basicUnsafeIndexM as i_
115 b <- G.basicUnsafeIndexM bs i_
116 return (Fingerprint a b)
117 {-# INLINE basicUnsafeCopy #-}
118 basicUnsafeCopy (MFingerprintVector as1 bs1) (FingerprintVector as2 bs2) = do
119 G.basicUnsafeCopy as1 as2
120 G.basicUnsafeCopy bs1 bs2
121 {-# INLINE elemseq #-}
122 elemseq _ (Fingerprint a b)
123 = G.elemseq (undefined :: Unboxed.Vector a) a
124 . G.elemseq (undefined :: Unboxed.Vector b) b
126data TypeRepVector f = TypeRepVect
127 { fingerprints :: Unboxed.Vector Fingerprint
128 , anys :: V.Vector Any
132fromAny = unsafeCoerce
135empty :: TypeRepVector f
136empty = TypeRepVect mempty mempty
138-- | Inserts the value with its type as a key.
139insert :: forall a f . Typeable a => a -> TypeRepVector f -> TypeRepVector f
142-- | Looks up the value at the type.
143-- >>> let x = lookup $ insert (11 :: Int) empty
148lookup :: forall a f . Typeable a => TypeRepVector f -> Maybe (f a)
149lookup tVect = fromAny . (anys tVect V.!)
150 <$> binarySearch (typeRepFingerprint (typeRep (Proxy :: Proxy a))) (fingerprints tVect)
152-- | Returns the size of the 'TypeRepVect'.
153size :: TypeRepVector f -> Int
154size = Unboxed.length . fingerprints
157 TF :: Typeable a => f a -> TF f
159fromF :: Typeable a => f a -> Proxy a
162fromList :: forall f . [TF f] -> TypeRepVector f
163fromList tfs = TypeRepVect (Unboxed.fromList fps) (V.fromList ans)
165 (fps, ans) = unzip $ sortWith fst $ map (fp &&& an) tfs
167 fp :: TF f -> Fingerprint
168 fp (TF x) = typeRepFingerprint $ typeRep $ fromF x
171 an (TF x) = unsafeCoerce x
173-- | Returns the index is found.
174binarySearch :: Fingerprint -> Unboxed.Vector Fingerprint -> Maybe Int
175binarySearch fp fpVect =
177 !(I# len) = Unboxed.length fpVect
178 ind = I# (binSearchHelp (-1#) len)
180 if fp == (fpVect Unboxed.! ind) then Just ind else Nothing
182 binSearchHelp :: Int# -> Int# -> Int#
183 binSearchHelp l r = case l <# (r -# 1#) of
186 let m = uncheckedIShiftRA# (l +# r) 1# in
187 if Unboxed.unsafeIndex fpVect (I# m) < fp
188 then binSearchHelp m r
189 else binSearchHelp l m
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list