module Bio.PDB.Structure.List(List(..), TempList,
initialNew, new, add, finalize, tempLength, empty, last,
singleton,
map, mapM, foldl, foldl', foldr, foldM, filter, length,
defaultSize, residueVectorSize, chainVectorSize,
toList, vimap, (!)
) where
import Prelude hiding (length, filter, drop, take, init, tail, mapM, splitAt, map, mapM, foldl, foldr, last)
import qualified Data.Vector.Mutable as M
import qualified Data.Vector as V
import Control.Monad(when)
import Control.DeepSeq(NFData(..))
import Control.Monad.State.Strict(lift)
import Data.STRef as ST
type List a = V.Vector a
data TempList m a = TempList !(ST.STRef m Int) !(ST.STRef m (M.MVector m a))
empty = V.empty
singleton= V.singleton
#ifdef DEFINE_NFDATA_VECTOR
instance NFData (V.Vector a) where
#endif
instance NFData (TempList m a) where
rnf t@(TempList i v) = i `seq` v `seq` ()
new i = lift $ initialNew i
initialNew i = do v <- M.new i
s <- ST.newSTRef 0
vs <- ST.newSTRef v
return $! TempList s vs
tempLength (TempList s v) = lift $ readSTRef s
residueVectorSize = 23
chainVectorSize = 150
defaultSize = 4
add (TempList s vs) a = lift $ do i <- readSTRef s
v <- readSTRef vs
when (i < 0) $ fail "Negative STRef"
let j = i + 1
l = M.length v
v' <- if (j > l)
then do nV <- M.grow v j
writeSTRef vs nV
return nV
else return v
M.write v' i a
ST.modifySTRef s (+1)
return ()
finalize (TempList s vs) = lift $ do i <- readSTRef s
when (i < 0) $ fail "Negative STRef"
v <- readSTRef vs
v' <- V.unsafeFreeze v
writeSTRef s (1)
return $! V.slice 0 i v'
foldl = V.foldl
foldl' = V.foldl'
foldr = V.foldr
map = V.map
filter = V.filter
mapM = V.mapM
foldM = V.foldM
length = V.length
last = V.last
toList = V.toList
vimap = V.imap
(!) = (V.!)